My problem is simple. How to Clear Focus of all the elements in a View that may have focus (like EditText
-or- TextView
whose textIsSelectable="true"
and the text is selected in it at occurrence of the clearFocus event).
Why am asking (in case I don't get a generic reply to above) :
I have few fragments that am accessing through Navigation View. My main goal is to lose focus of the elements in the fragment on Drawer open in Navigation View. I know its possible to get onDrawerSlide
method for the NavigationDrawer and have infact set it up in my MainActivity so that on drawer open, if my EditText in one of the Fragments is open, I call hideSoftKeyboard code so that it closes the SoftKeyboard.
My Code to get the event on Opening of Drawer: (in onCreate() method of 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)
{
//Hide SoftKeyboard on Navigation Drawer Open
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
//Hide SoftKeyboard if it is open
hideSoftKeyboard();
//And Make any view having focus loose focus
//...
//ClearFocus for the whole view is done from here (for whichever Fragment is visible right now)
super.onDrawerSlide(drawerView, slideOffset);
}
};
public void hideSoftKeyboard() //Declared outside onCreate
{
InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
Here, my hideSoftKeyboard() code is generic and can close SoftKeyboard no matter what Fragment is visible at the moment from the MainActivity itself. Similarly I want to clearFocus of all my EditTexts and TextView (since Copy/Paste option shows up in middle of the drawer when it is open).
I know I can write code for each Fragment calling onDrawerSlide function and clearing Focus for each element individually, but I want to know if it is possible for a generic solution and if so, how to do it.
(If it is possible, there might be many implications of this and may help in a lot many cases)
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.