Search code examples
androidandroid-jetpack-compose

Strange scroll in the BasicTextField with IntrinsicSize.Min


I need to implement UI control(decrease button, resizeable text input, increase button)

I was trying both ways - compose and XML version.

  1. Compose version. I have a strange scroll when I click on BasicTextField and pull horizontally. It just hides TextField value.

     BasicTextField(
         value = text,
         keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
         keyboardActions = remember { KeyboardActions(onDone = { keyboardController?.hide() }) },
         onValueChange = { onTextChanged(it) },
         singleLine = true,
         decorationBox = { innerTextField ->
             Box(modifier = Modifier.width(IntrinsicSize.Min)) {
                 innerTextField()
             }
         }
     )
    

Modifier.width(1.dp, Dp.Infinity), doesn't help and takes empty horizontal padding, but it doesn't have the "internal" scroll.

1.1. How to fix the "internal" scroll in the BasicTextField with applied IntrinsicSize.Min?

1.2. Also BasicTextField cuts the left-most digit when you put cursor position. It would be great to have the same behavior as we have in the XML version.

  1. XML version. I was trying to use the XML version with EditText instead of Compose BasicTextField but stuck with merge compose state and EditText TextWatcher listener.

2.1. To avoid twice setting the same text value to the EditText, I should compare compose state value and EditText value each time in the update {} block, is that ok? Or here can be a better solution?

        AndroidView(
            factory = {
                _binding = L7Binding.inflate(inflater, container, false)
                val view = _binding!!.root
                _binding!!.editText.doOnTextChanged { text, _, _, _ ->
                    viewModel.onTextChanged(text.toString())
                }
                view
            },
            update = {
                if (_binding!!.editText.text.toString() != inputText) {
                    _binding!!.editText.setText(inputText)
                } 
            }
        )

enter image description here


Solution

  • I faced the same problem. Solved it with the help of this code, I hope it will be useful to you)

    BasicTextField(,
        modifier =  Modifier
            .disabledHorizontalPointerInputScroll()...
    

    and also

        private val HorizontalScrollConsumer = object : NestedScrollConnection {
        override fun onPreScroll(available: Offset, source: NestedScrollSource) = available.copy(y = 0f)
        override suspend fun onPreFling(available: Velocity) = available.copy(y = 0f)
    }
    
    fun Modifier.disabledHorizontalPointerInputScroll(disabled: Boolean = true) =
        if (disabled) this.nestedScroll(HorizontalScrollConsumer) else this