Reputation: 531
I have text field and it has its own custom input UI on the way. The Problem is i need to use my custom input, and do not want the keyboard to open when focus is gained on the text field. I don't want to set the text field as read only because it removes the ability to focus and edit, But i need the text field to be focusable and editable.
TextField(
value = text,
onValueChange = { newText ->
// Update the text with validation for digits
if (newText.all { it.isDigit() } && newText.length <= 10) {
text = newText
}
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
modifier = Modifier.fillMaxWidth(),
label = { Text("Enter numbers") }
)
Upvotes: 1
Views: 80
Reputation: 530
okay so what i understand is you need a custom input ( probably something similar to custom on-screen keyboard ) instead of the traditional soft-keyboard
val interactionSource = remember { MutableInteractionSource() }
TextField(
value = text,
onValueChange = { newText ->
// Update the text with validation for digits
if (newText.all { it.isDigit() } && newText.length <= 10) {
text = newText
}
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
modifier = Modifier.fillMaxWidth(),
label = { Text("Enter numbers") },
interactionSource = interactionSource // add an interactionSource
)
val coroutineScope = rememberCoroutineScope()
val keyboardController = LocalSoftwareKeyboardController.current
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
when (interaction) {
is PressInteraction.Release -> {
coroutineScope.launch {
keyboardController?.hide() // Hide the keyboard on finger release ( similar to the end event of tap, touch, click )
Log.d("MyTag","KeyBoard Hidden")
}
}
}
}
}
so basically everytime an Release event ( Read more ) is called, then hide the soft-keyboard using keyboardController?.hide()
,why am i using release event is because it refers to the pointer/finger being lifted up after press,touch,click,tap etc.. , it may sometimes trigger Cancel event ( Read more ), but when cancel event is triggered, it means the previous event such as press is cancelled, if cancelled it wont trigger the soft-keyboard to popup, and release means the event has been occurred => triggering the popup of soft-keybaord, so when the popup of soft-keyboard is triggered on Release Event then => hide the soft-keyboard using keyboardController?.hide()
so for your requirement that is hiding/closing the soft-keyboard for the edit-text ( textField ), you have make few changes to setOnTouchListener
, setOnFocusChangeListener
and addTextChangedListener
Follow the below steps and add the following inside onCreate method
imm
variableval editText: EditText = findViewById(R.id.editTextText)
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
OnTouchListener
, and return true, returning true means or tells other OnTouchListener
to not perform actions on this field, ( meaning the event has been captured/handled by this listener, no need for further operations ), and the call .requestFocus()
, to display the blinking cursoreditText.setOnTouchListener { _, _ ->
editText.requestFocus()
true
}
OnFocusChangeListener
, and return true, ( same as OnTouchListener
), and using hideSoftInputFromWindow
to hide the keyboardeditText.setOnFocusChangeListener{ _, _ ->
imm.hideSoftInputFromWindow(editText.windowToken, 0)
true
}
addTextChangedListener
, to set the blinking cursor position at the end of text present in the text field, and added hideSoftInputFromWindow
to hide/close keyboard if open, everytime the text is changededitText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(
charSequence: CharSequence?,
start: Int,
count: Int,
after: Int
) {
// Code to handle before text change
}
override fun onTextChanged(
charSequence: CharSequence?,
start: Int,
before: Int,
count: Int
) {
imm.hideSoftInputFromWindow(editText.windowToken, 0)
editText.setSelection(editText.text.length)
}
override fun afterTextChanged(editable: Editable?) {
// Code to handle after text change
}
})
so we are overriding the setOnTouchListener
and setOnFocusChangeListener
methods to prevent the default behaviour of the text field, of
and then making required changes to add the following feature to the text field
above i used hideSoftInputFromWindow
to hide the keyboard, which was not necessary, but considering the conditions of screen rotation ( landscape to potrait ) or if some way the soft-keyboard is popped up, it will automatically hide/close it upon interacting with any text field
you could achieve the same using a less simple and small code, BUT THAT IS MESSY AND GIVES A BUGGY FEELING OF UI
editText.setOnFocusChangeListener{ view, _ ->
val handler = Handler(Looper.getMainLooper())
handler.postDelayed({
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(editText.windowToken, 0)
}, 1)
}
the above code provides the required solution but randomly show the soft-keyboard for a split second and then hides it, ( it doesnt look visually appealing, you could still try it if needed )
I hope you found this useful, informative, solved your problem and met your specific requirements, Any doubts related to anything feel free to ask
Upvotes: 1