How do I use the Android soft keyboard to receive key press events while supporting text suggestion and other features?

299 Views Asked by At

I have a custom text entry rendered via SkiaSharp in my Xamarin project, and I need to access the Android keyboard so that I can enter text. I can bring up the keyboard using:

Window.DecorView.WindowInsetsController.Show(WindowInsetsCompat.Type.Ime());

However when I do this, the soft keyboard doesn't have any features like text suggestions and just displays the english keyboard when you select the korean or japanese keyboard (I have them enabled on my phone and work in other apps).

I realised I could get more soft keyboard features and also extra keyboard languages if I called the same function above but on an TextView as such:

// In MainActivity.cs

private CustomTextView tv;

protected override void OnCreate(Bundle savedInstanceState)
{
    ...

    // Adding the text view to the Xamarin Forms view group.
    if (Window.DecorView.FindViewById(Android.Resource.Id.Content) is ViewGroup viewGroup)
    {
        tv = new CustomTextView(this); // tv is defined in the class.
        tv.SetOnKeyListener(new CustomKeyListener());
        viewGroup.AddView(tv);
    }
}

// I call this elsewhere when I want the keyboard.
public void SummonKeyboard()
{
    tv.RequestFocus();
    tv.RequestFocusFromTouch();
    tv.WindowInsetsController.Show(WindowInsetsCompat.Type.Ime());
}

However the problem is that then it blocks me from receiving any key press event either through the IOnKeyEventListener or from overriding the various OnKey... functions from the EditText. The only way I can get any input from it is via the TextChanged event but this is insufficient for my needs as I need to extract exact key presses.

My class CustomTextView looks as such:

internal class CustomTextView : TextView
{
    public CustomTextView(Context context) : base(context)
    {
        Focusable = true;
        FocusableInTouchMode = true;

        InputType = Android.Text.InputTypes.ClassText;
    }
}

My class CustomKeyListener looks as such:

internal class CustomKeyListener : Java.Lang.Object, View.IOnKeyListener
{
    public bool OnKey(View v, [GeneratedEnum] Keycode keyCode, KeyEvent e)
    {
        Debug.WriteLine($"Key press triggerred"); // This is never called.
        return false;
    }
}

How can I use the full Android soft keyboard while still receiving key inputs?

1

There are 1 best solutions below

0
Jianwei Sun - MSFT On BEST ANSWER

However the problem is that then it blocks me from receiving any key press event either through the IOnKeyEventListener or from overriding the various OnKey... functions from the EditText.

The native android official document about the KeyBoard event said:

Note: When handling keyboard events with the KeyEvent class and related APIs, expect that the keyboard events are coming only from a hardware keyboard. Never rely on receiving key events for any key on a soft input method (an on-screen keyboard).

So you can't get the key code from the soft keyboard event. This is android native limit.

But if it's physical keyboard, you can use KeyEvent. And you can see this example: MAUI How to use KeyEvent.Callback in an Android app.