Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force EditText to lose focus when back pressed

I'm trying to force the EditText control to lose focus when the user presses the back button to hide the keyboard. There are many questions similar to this already, but after several hours, I haven't been able to make it work.

First, just a little bit of context. I have a ListView with custom items. Each item has several TextViews and one EditText. I have an AfterTextChanged() method saving edited values. I have a style set up to highlight the field if it has focus. Unfortunately, it is now much more obvious that the EditText doesn't actually lose focus when you hide the (soft) keyboard, and I think it's confusing. I would like the EditText to not be focused if there's no keyboard.

The solution that seemed the most reasonable is to override OnBackPressed() in the activity as described here. Unfortunately, it doesn't appear that my method is being called. I.e. the field is still focused, and a breakpoint in the function doesn't fire.

Similarly, an OnKeyUp() listener on the activity doesn't fire, and Xamarin doesn't appear to support the OnKeyUp handler for the EditText control.

I'm not trying to suppress the keyboard on creation, or anything, so using any of the invisible control tricks don't help either.

It's obvious that a lot of people have this problem. I'm sure one of you has solved it! Can you please share your solution?

Thank you so much! -Karen

P.S. I do not need to know how to hide the keyboard. I need to take an action when the user hides the keyboard with the back button. Thanks :)

like image 380
Karen Cate Avatar asked Aug 12 '13 22:08

Karen Cate


2 Answers

In my experience onBackPressed() (at least the default @Override one in an activity) will not normally fire when pushing the back button to close the keyboard. As far as I know it will only fire when a Back press would initiate a finish() on the current activity.

Below is a kind of "hacky" way to know when the keyboard is shown/hidden by monitoring the change in the view size. You must also set the Activity to android:windowSoftInputMode="adjustResize" in the AndroidManifest.xml.

final View activityRootView = findViewById("Your main View");
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        Rect r = new Rect();
        //r will be populated with the coordinates of your view that area still visible.
        activityRootView.getWindowVisibleDisplayFrame(r);

        int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
        if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
          //Keyboard is shown


        }
        if(heightDiff <= 100) {
            //Keybaord not shown
        }
     }
    });
like image 77
Shadesblade Avatar answered Sep 27 '22 19:09

Shadesblade


With sincere thanks to @Shadesblade (and Xamarin's sample code), my EditTexts now unfocus! Here's the Xamarin-ized solution:

To your activity, add this class:

class GlobalLayoutListener : Java.Lang.Object, ViewTreeObserver.IOnGlobalLayoutListener
{
    Action on_global_layout;
    public GlobalLayoutListener (Action onGlobalLayout)
    {
        on_global_layout = onGlobalLayout;
    }

    public void OnGlobalLayout ()
    {
        on_global_layout ();
    }
}

Add a class variable to hold the View so that the delegate can access it:

View _rootview;

In your OnCreate() add:

GlobalLayoutListener gll = new GlobalLayoutListener(
    delegate {
        Android.Graphics.Rect r = new Android.Graphics.Rect();
        _rootView.GetWindowVisibleDisplayFrame(r);
        int heightDiff = _rootView.RootView.Height - (r.Bottom - r.Top);
        if (heightDiff < 100)
        {
            if (Window.CurrentFocus != null)
                Window.CurrentFocus.ClearFocus();
        }
    });

_rootView = FindViewById<View>(Resource.Id.relativeLayoutOrder);
_rootView.ViewTreeObserver.AddOnGlobalLayoutListener(gll);

I expect to need to dork around with the heightDiff level and/or have to add some rotation checking, but I haven't done any rotation support at this point, so I can punt that until later.

Thank you again! *happy dance*

like image 36
Karen Cate Avatar answered Sep 27 '22 21:09

Karen Cate