How to clear focus of all selectable elements in a View?
If you have multiple activity and in those activities only one activity you have Navigation View. In that case if you want to clear focus on navView use this code,
@Override
protected void onResume() {
super.onResume();
int size = navigationView.getMenu().size();
for (int i = 0; i < size; i++) {
navigationView.getMenu().getItem(i).setChecked(false);
}
}
Well, I finally decided I couldn't wait any longer for a general answer and so decided to implement the onDrawerSlide
for each fragment. Turns out, even that is a bit tricky since you need to access your toolbar and setup your drawer using current drawer and a little bit of experimenting was throwing up NPE! (Just my usual luck)
So was going through the official android developers site for any insight when this flashed to me. Why not use getCurrentFocus
to get my present view and then clearFocus()
! And voilla, it works. I was focusing on the complex situation so much that I forgot to check on the easy parts.
So here's the answer to my own question: (in onCreate for MainActivity)
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
{
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
hideSoftKeyboard();
getCurrentFocus().clearFocus(); //clear focus - any view having focus
super.onDrawerSlide(drawerView, slideOffset);
}
Thanks to @keivan Esbati for pointing out a loophole that I didn't notice due to my usage of dummy view (used in layout xml so that as soon as Layout is loaded, the first EditText does not get the focus). As per Android Developer forum :
clearFocus() : When a View clears focus the framework is trying to give focus to the first focusable View from the top. Hence, if this View is the first from the top that can take focus, then all callbacks related to clearing focus will be invoked after which the framework will give focus to this view.
A round-about to this is ofcourse to set up a dummy variable that calls focus as soon as Layout is loaded (method I used) or this as shared by @keivan.
To Clear focus from a View you can call getCurrentFocus().clearFocus()
But remember that this will Simply move focus from current view to the first element in your view, not Completely removing focus from views; So if the first element in your layout is a EditText
it's going to gain focus again.
A way to make sure your view doesn't get focus again is to add this attributes to your root view in your xml, enabling root view to capture focus:
android:focusableInTouchMode="true"
android:descendantFocusability="beforeDescendants"
So if you declare your root element like below it gonna automatically catch focus before it reach the child views:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:descendantFocusability="beforeDescendants">
<!-- Rest of Layout -->
<.../>
</LinearLayout>