Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I implement custom View for keyboard after Keyboard has been deprecated?

Tags:

I am using latest Android Studio and Kotlin to make a system keyboard for Android (API 100% users). I am trying to follow the IME life cycle.

There is this guideline on overriding onCreateInputView()

override fun onCreateInputView(): View {     return layoutInflater.inflate(R.layout.input, null).apply {         if (this is MyKeyboardView) {             setOnKeyboardActionListener(this@MyInputMethod)             keyboard = latinKeyboard         }     } } 

where MyKeyboardView is an instance of a custom implementation of KeyboardView that renders a Keyboard.

The problem only rose because android.inputmethodservice.KeyboardView has been deprecated since API level 29. The document says

This class is deprecated because this is just a convenient UI widget class that application developers can re-implement on top of existing public APIs.

I do not want to use a deprecated feature but the guide has not been updated accounting for this change. The brutal way of making my own would be just making a ton of buttons in constraint layout. Is this the correct way? As a complete beginner, I am lost as soon as I cannot follow the guide.

like image 274
Seung Avatar asked Aug 24 '19 01:08

Seung


People also ask

How do I change the Done button on my Android keyboard?

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.

How to get old deprecated keyboardview and keyboard Android classes?

The only solution Google suggests is copying KeyboardView.java and Keyboard.java files to your local project from Android AOSP. With some customization I managed to make it work as old deprecated KeyboardView and Keyboard Android's classes.

How do I dismiss the keyboard on a ScrollView?

Some people suggest replacing the View with a ScrollView as it has keyboard dismissing ability built-in. By default, tapping outside of an input on a ScrollView will automatically dismiss the keyboard. Adding keyboardDismissMode="on-drag" will also allow the keyboard to dismiss if the view is dragged.

How do I change the keyboard layout?

Grant the app admin permission to install (The keyboard is installed for the current language). Go to Time & Language. Select the current language. Click the keyboard button under it. The current and new keyboard layout will be listed.

How do I hide the keyboard in a React Native view?

Learn how here. When using a View in React Native, you don't have any control over the keyboard. So, if the view has an input field and the user taps away from the input field, the keyboard will remain visible. The user has no way to get rid of the keyboard.


1 Answers

It is clear, from the docs here :

This class was deprecated in API level 29. This class is deprecated because this is just a convenient UI widget class that application developers can re-implement on top of existing public APIs. If you have already depended on this class, consider copying the implementation from AOSP into your project or re-implementing a similar widget by yourselves

This means that you have to create your own view with all the keys, which also means handling all the click events like enter, delete and switching keyboards eg. to symbols etc. by yourself.

Actually there are many ways to do it. But I will try to give you a simple idea, you will follow most of the steps that you used while using the deprecated KeyboardView:

First create your custom keyboard layout, you can use any layout depending what is convenient for you like LinearLayout, RelativeLayout and Buttons for the keys etc. I used a GridLayout with Buttons.

Then create the subclass of InputMethodService as usual:

public class MyIMService extends InputMethodService implements View.OnClickListener {      private static String TAG = "MyIMService";      @Override     public View onCreateInputView() {         View myKeyboardView = getLayoutInflater().inflate(R.layout.key_layout, null);         Button btnA = myKeyboardView.findViewById(R.id.btnA);         btnA.setOnClickListener(this);         //ADD ALL THE OTHER LISTENERS HERE FOR ALL THE KEYS         return myKeyboardView;     }      @Override     public void onClick(View v) {         //handle all the keyboard key clicks here          InputConnection ic = getCurrentInputConnection();         if (v instanceof Button) {             String clickedKeyText = ((Button) v).getText().toString();             ic.commitText(clickedKeyText, 1);         }     } } 

As I said earlier you can try a different way of handling all the click events. But this should give you the basic idea.

That's it. You have to add this service in your manifest file as usual and also the other steps as usual. This should work now.

UPDATE Kotlin version:

class MyIMService : InputMethodService(), View.OnClickListener {     override fun onCreateInputView(): View {         val myKeyboardView: View = layoutInflater.inflate(R.layout.key_layout, null)         val btnA: Button = myKeyboardView.findViewById(R.id.btnA)         btnA.setOnClickListener(this)         //ADD ALL THE OTHER LISTENERS HERE FOR ALL THE KEYS         return myKeyboardView     }      override fun onClick(v: View) {         //handle all the keyboard key clicks here         val ic = currentInputConnection         if (v is Button) {             val clickedKeyText: String = (v as Button).getText().toString()             ic.commitText(clickedKeyText, 1)         }     }      companion object {         private const val TAG = "MyIMService"     } } 
like image 136
Nongthonbam Tonthoi Avatar answered Oct 06 '22 11:10

Nongthonbam Tonthoi