I am trying to implement a TextField which inputs an amount and formats it as soon as it is typed and also limits it to 100,000.
@Composable
fun MainScreen(
viewModel: MyViewModel
) {
val uiState by viewModel.uiState.collectAsState()
Column {
AmountSection(
uiState.amount,
viewModel::updateAmount
)
Text(text = viewModel.logs)
}
}
@Composable
fun AmountSection(
amount: TextFieldValue,
updateAmount: (TextFieldValue) -> Unit
) {
BasicTextField(
value = amount,
onValueChange = updateAmount,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number
)
)
MyViewModel:
class MyViewModel: ViewModel() {
private val _uiState = MutableStateFlow(MyUiState())
val uiState: StateFlow<MyUiState> = _uiState
var logs by mutableStateOf("")
var text = ""
fun updateAmount(amount: TextFieldValue) {
val formattedAmount: String = amount.text.getFormattedAmount()
text += "input = ${amount.text}\n"
text += "output = $formattedAmount \n"
logs = text
_uiState.update {
it.copy(amount = TextFieldValue(formattedAmount, TextRange(formattedAmount.length))
}
}
}
data class MyUiState(val amount: TextFieldValue = TextFieldValue())
(logs
and text
are just for logging purpose. Was finding it difficult to share the logcat output so presented it this way)
Result:
- When I press 6, the input is "12,3456" which is expected (ignore the currency)
- My
getFormattedAmount()
function removes the last six as ( 123456 > 100000). It outputs "12,345" which is also correct. "12,345" is what gets displayed on the screen. - But when I press 7, I get the input "12,34567". Where did that 6 come from?? It was not in
uiState.amount
.
(Please ignore the last output line. getFormattedAmount
only removes the last character if the amount exceeds the limit and it gave wrong output because it didn't expect that input)
I feel that I making some really silly mistake here and would be really thankful if somecome could help me find that out.