Как применить преобразование ввода для TextField в Jetpack Compose?Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Как применить преобразование ввода для TextField в Jetpack Compose?

Сообщение Anonymous »

Я работаю над приложением Jetpack Compose, где мне нужно преобразовать пользовательский ввод в BasicTextField, чтобы по мере ввода пользователем ввод динамически форматировался с включением разделителей. Например, если пользователь вводит 123456789, текст должен преобразоваться в ABC-1234-5678-9101 в реальном времени. Это необходимо, поскольку мой API ожидает ввода в этом конкретном формате.
В настоящее время я добился этого с помощью выводаTransformation со следующей настройкой:

Код: Выделить всё

@Stable
data class GroupingOutputTransformation(
private val groupSize: Int,
private val groupDelimiter: String,
) : OutputTransformation {
override fun TextFieldBuffer.transformOutput() {
repeat((length - 1) / groupSize) {
insert(it + (it + 1) * groupSize, groupDelimiter)
}
}
}
Мне удалось применить аналогичное преобразование для ввода, используя обходной путь: отслеживая state.text и обновляя значение с помощью:

Код: Выделить всё

textFieldValue = "ABC-" + state.text.chunked(4).joinToString("-")
Это работает, но больше похоже на хак, а не на идиому. Моя цель — реализовать чистый идиоматический подход к inputTransformation для достижения такого форматирования, гарантируя:
  • Ввод динамически форматирует текст в реальном времени. (например, ABC-1234-5678-9101).
  • Базовые данные соответствуют требуемому формату API.
  • Это позволяет избежать взлома ручного управления состоянием или избыточность.
Полный код

Код: Выделить всё

class MainActivity : ComponentActivity() {

private lateinit var binding: MainActivityBinding

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
BasicTextFieldExampleTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Column(
Modifier.fillMaxSize()
) {
BasicTextFieldExample(innerPadding)
}
}
}
}
}
}

@Composable
fun BasicTextFieldExample(innerPadding: PaddingValues) {
val state = rememberTextFieldState()
var buttonText by remember { mutableStateOf("Get text") }
var textFieldValue by remember { mutableStateOf("") }
val interactionSource = remember { MutableInteractionSource() }

LaunchedEffect(Unit) {
snapshotFlow { state.text }
.collectLatest {
textFieldValue = it.toString()
}
}

Column {
BasicTextFieldView(
modifier = Modifier
.padding(innerPadding)
.wrapContentSize(),
state = state,
interactionSource = interactionSource,
prefix = {
Text(
"Abc-"
)
}
)
Spacer(Modifier.height(100.dp))
Button(onClick = {
buttonText = "ABC-" + textFieldValue.chunked(4).joinToString("-")
}) {
Text(buttonText)
}
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BasicTextFieldView(
modifier: Modifier,
state: TextFieldState,
interactionSource: MutableInteractionSource,
prefix: @Composable () -> Unit,
) {

Column(modifier) {
BasicTextField(
state = state,
modifier = Modifier
.fillMaxWidth()
.padding(20.dp),
interactionSource = interactionSource,
inputTransformation = InputTransformation.maxLength(12),
outputTransformation = GroupingOutputTransformation(4, "-"),
enabled = true,
lineLimits = TextFieldLineLimits.SingleLine,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
textStyle = LocalTextStyle.current,
decorator = {
TextFieldDefaults.DecorationBox(
value = state.text.toString(),
innerTextField = it,
enabled = true,
label = {
Text(
"Label"
)
},
isError = false,
interactionSource = interactionSource,
prefix = prefix,
singleLine = true,
visualTransformation = VisualTransformation.None
)
}
)
}
}
Ссылка из этого вопроса.

Подробнее здесь: https://stackoverflow.com/questions/793 ... ck-compose
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»