Xamarin.Android: Key Listener not working

2.1k Views Asked by At

In the OnCreate fragment method, I get my EditText from the layout and call SetOnKeyListener:

Aaa = view.FindViewById<EditText>(Resource.Id.aaaText);
Aaa.SetOnKeyListener(new LocationKeyListener());

Layout declaration:

<EditText 
            android:id="@+id/aaaText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:imeOptions="actionNext"
            style="@style/LocationEditTextStyle"
            android:hint="AAA"
            app:MvxBind="Text Aaa.Value"/>

EditText styles:

<style name="LoginEditTextTheme" parent="Theme.AppCompat">
        <item name="colorControlNormal">@color/accentColor</item>
        <item name="colorControlActivated">@color/secondaryTextColor</item>
    </style>


    <style name="LocationEditTextStyle" parent="Widget.AppCompat.EditText">
        <item name="android:textAllCaps">true</item>
        <item name="android:inputType">textCapCharacters</item>
        <item name="android:maxLength">3</item>
        <item name="android:gravity">center_horizontal</item>
        <item name="android:textSize">@dimen/location_text_size</item>
        <item name="android:theme">@style/LocationEditTextTheme</item>
    </style>

LocationKeyListener:

enter image description here

The problem is that the LocationKeyListener.OnKey method is not called, when I write in EditText.

UPDATE

My Fragment with Edit texts:

public abstract class BaseActionFragment<T> : BaseFragment<T> where T : BaseViewModel
    {
        protected EditText Aaa, Bbb, Ccc, Ddd, Eee;
        protected EditText test;


        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View view = base.OnCreateView(inflater, container, savedInstanceState);

            Aaa = view.FindViewById<EditText>(Resource.Id.aaaText);
            Bbb = view.FindViewById<EditText>(Resource.Id.bbbText);
            Ccc = view.FindViewById<EditText>(Resource.Id.cccText);
            Ddd = view.FindViewById<EditText>(Resource.Id.dddText);
            Eee = view.FindViewById<EditText>(Resource.Id.eeeText);

            Aaa.AddLocationTextWatcher(Aaa, Bbb);
            Bbb.AddLocationTextWatcher(Aaa, Ccc);
            Ccc.AddLocationTextWatcher(Bbb, Ddd);
            Ddd.AddLocationTextWatcher(Ccc, Eee);
            Eee.AddLocationTextWatcher(Ddd, Aaa);

            test = view.FindViewById<EditText>(Resource.Id.testText);

            test.SetOnKeyListener(new LocationKeyListener());
            test.KeyPress += (sender, args) =>
            {

            };

            return view;
        }
    }

Here is My Main Container View:

 [Activity(
        Theme = "@style/AppTheme")]
    public class MainContainerActivity : BaseActivity<MainContainerViewModel>, IDrawerActivity
    {
        protected override int ActivityLayoutId => Resource.Layout.activity_main_container;

        public DrawerLayout DrawerLayout { get; private set; }
        protected MvxActionBarDrawerToggle DrawerToggle { get; private set; }

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            DrawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);

            SetupDrawerLayout();
            DrawerToggle.SyncState();

            if (bundle == null)
                ViewModel.ShowMenuCommand.Execute();
        }

        private void SetupDrawerLayout()
        {
            SupportActionBar?.SetDisplayHomeAsUpEnabled(true);

            DrawerToggle = new MvxActionBarDrawerToggle(
                this,                           // host Activity
                DrawerLayout,                   // DrawerLayout object
                Toolbar,                        // nav drawer icon to replace 'Up' caret
                Resource.String.drawer_open,    // "open drawer" description
                Resource.String.drawer_close    // "close drawer" description
            );

            DrawerToggle.DrawerOpened += (sender, e) => HideSoftKeyboard();
            DrawerLayout.AddDrawerListener(DrawerToggle);
        }

        public override void OnBackPressed()
        {
            if (DrawerLayout != null && DrawerLayout.IsDrawerOpen(GravityCompat.Start))
                DrawerLayout.CloseDrawers();
            else
                base.OnBackPressed();
        }

        public override void OnConfigurationChanged(Configuration newConfig)
        {
            base.OnConfigurationChanged(newConfig);
            DrawerToggle.OnConfigurationChanged(newConfig);
        }


        public void HideSoftKeyboard()
        {
            if (CurrentFocus != null)
            {
                var inputMethodManager = (InputMethodManager)GetSystemService(InputMethodService);
                inputMethodManager.HideSoftInputFromWindow(CurrentFocus.WindowToken, 0);

                CurrentFocus.ClearFocus();
            }
        }
    }

Perhaps this is due to the fact that all this is in the Fragment

1

There are 1 best solutions below

0
On

Although this is an old topic, but I ran into the same issue, just be aware that View.IOnKeyListener does not support SoftKeyboard (virtual keyboard) key inputs. Only hardware keyboard input is performed via OnKey event.

Depending on your usecase, if you want to get notified if E.g. any softkeyboard button is pressed (like Keycode.NavigateNext button) than use EditorAction event. In Xamarin.Forms E.g. define a custom entry renderer and in the OnElementChanged event listen on the event via:

this.EditText.EditorAction += EditTextOnEditorAction;

Than handle any key action which your are interested in:

private void EditTextOnEditorAction(object sender, TextView.EditorActionEventArgs e)
{
    if (e.ActionId == ImeAction.Next)
    {
        var formsNextSearch = FocusSearchNextElement();
        if (formsNextSearch != null)
        {
            EditText.ClearFocus();                   
        }
    }
}

Android Keyboard-Input docu