1

I am working on a Xamarin Forms project for which one requirement is to recognize certain key presses to trigger hot key actions. The devices that we will be deploying the application to have physical keyboards attached. For now, Android is the only platform that is being targeted.

From some research that I did yesterday afternoon, it sounds as though a custom page renderer is what is required. As I played with this concept this morning, I stumbled upon the On* key methods of the Activity class.

I tried adding the following to the MainActivity class in the Android project:

public override bool OnKeyUp([GeneratedEnum] Keycode keyCode, KeyEvent e)
{
    return base.OnKeyUp(keyCode, e);
}

Placing a breakpoint on this method seems to show that this code is what is needed (read, this method is fired whenever I press a key on the keyboard).

The issue is that this method is also fired when an Entry control on the page has focus. Shouldn't the key press be handled by the Entry control and not bubbled up to the page?

Generally speaking, is this the right approach for what I am trying to accomplish? Are there other approaches that someone can point me to that might work better?

1
  • I beleive that best approach would be to handle the entry input in a viewmodel and firing the logic from there to the view. Commented Aug 9, 2019 at 17:34

1 Answer 1

1

When I was working with hardware devices, I had to do something similar. I created a custom renderer for an entry on the Xamarin.android side. This captures the Enter key press for both hard and soft key in different events. I think creating custom render for a page like you did could work too but this only captures key presses for elements that are in focus. This works for me as I have the entry in focus when user presses the hardware Enter key.

    [assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
    namespace Project.Droid.Controls {
        public class CustomEntryRenderer : EntryRenderer {

            public CustomEntryRenderer(Context context) : base(context) {


            }

            protected override void OnElementChanged(ElementChangedEventArgs<Entry> e) {
                base.OnElementChanged(e);

                Control.EditorAction += Control_EditorAction;
                Control.KeyPress += NativeEditText_KeyPress;
            }



            // Fires only for Soft Keyboard
            private void Control_EditorAction(object sender, Android.Widget.TextView.EditorActionEventArgs e) {
                if (e.ActionId == ImeAction.Done) {
                    // your code
                    e.Handled = true;
                }
            }

            // Fires for Hard Keyboard
            private void NativeEditText_KeyPress(object sender, KeyEventArgs e) {
                if (e.KeyCode == Keycode.Enter && e.Event.Action == KeyEventActions.Up) {
                    // your code
                    e.Handled = true;
                }
                else
                    e.Handled = false;
            }

        }
    }

FYI: I also tried the MainActivity event that you are using and it did not work for me. I cannot recall why.

Sign up to request clarification or add additional context in comments.

2 Comments

I think I might be going in a slightly different direction than what you described. I am going to mark your answer as the accepted solution as it put me on a correct path.
Thanks. Please let me know what path you finally took. Would be good to know.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.