I am trying to use the done button of the soft keyboard to activate a method via databinding. Just like onClick. Is there a way to do that?
example:
<EditText
android:id="@+id/preSignUpPg2EnterPhone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
onOkInSoftKeyboard="@{(v) -> viewModel.someMethod()}"
/>
onOkInSoftKeyboard doesn't exists... Is there something to create this behavior?
Thanks!
First you need to set the android:imeOptions attribute equal to “actionDone” for your target EditText as seen below. That will change your 'RETURN' button in your EditText's soft keyboard to a 'DONE' button.
As stated in Android Documentation, IME Action directs the keyboard what type of action should be displayed. This depends on you (the developer) to change the IME Action according to your needs. For example, a text field intended to be used as a search bar would contain the search IME Action and so on…
android:imeOptions="actionSend" /> You can then listen for presses on the action button by defining a TextView.OnEditorActionListener for the EditText element. In your listener, respond to the appropriate IME action ID defined in the EditorInfo class, such as IME_ACTION_SEND . For example: Kotlin Java.
You can force Android to hide the virtual keyboard using the InputMethodManager, calling hideSoftInputFromWindow , passing in the token of the window containing your focused view. This will force the keyboard to be hidden in all situations. In some cases, you will want to pass in InputMethodManager.
I won't claim to be an expert in onEditorAction()
or soft keyboard. That said, assuming you use the solution to the stack overflow question Firoz Memon suggested, you can make it happen. Even if there is another solution that works better, this can give you an idea on how to add your own event handlers.
You'd need a binding adapter that takes some kind of handler. Let's assume you have an empty listener like this:
public class OnOkInSoftKeyboardListener {
void onOkInSoftKeyboard();
}
Then you need a BindingAdapter:
@BindingAdapter("onOkInSoftKeyboard") // I like it to match the listener method name
public static void setOnOkInSoftKeyboardListener(TextView view,
final OnOkInSoftKeyboardListener listener) {
if (listener == null) {
view.setOnEditorActionListener(null);
} else {
view.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public void onEditorAction(TextView v, int actionId, KeyEvent event) {
// ... solution to receiving event
if (somethingOrOther) {
listener.onOkInSoftKeyboard();
}
}
});
}
}
Using Kotlin, kapt produces:
e: [kapt] An exception occurred: android.databinding.tool.util.LoggedErrorException: Found data binding errors.
****/ data binding error ****msg:Listener class kotlin.jvm.functions.Function1 with method invoke did not match signature of any method viewModel::signIn
(because viewModel::signIn
is of type KFunction1
) so we can't use a method reference. However, if we create a variable within the viewModel
that is explicit about the type, then we can pass that variable as the binding's param. (or just use a class)
Bindings.kt:
@BindingAdapter("onEditorEnterAction")
fun EditText.onEditorEnterAction(f: Function1<String, Unit>?) {
if (f == null) setOnEditorActionListener(null)
else setOnEditorActionListener { v, actionId, event ->
val imeAction = when (actionId) {
EditorInfo.IME_ACTION_DONE,
EditorInfo.IME_ACTION_SEND,
EditorInfo.IME_ACTION_GO -> true
else -> false
}
val keydownEvent = event?.keyCode == KeyEvent.KEYCODE_ENTER
&& event.action == KeyEvent.ACTION_DOWN
if (imeAction or keydownEvent)
true.also { f(v.editableText.toString()) }
else false
}
}
MyViewModel.kt:
fun signIn(password: String) {
Toast.makeText(context, password, Toast.LENGTH_SHORT).show()
}
val signIn: Function1<String, Unit> = this::signIn
layout.xml:
<EditText
android:id="@+id/password"
app:onEditorEnterAction="@{viewModel.signIn}"
android:imeOptions="actionDone|actionSend|actionGo"
android:singleLine="true"/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With