In my app, I'm making a search interface in which the SearchView
collapses and expands when it loses and gains focus respectively. However, the losing focus thing is only happening in two cases:
When the back button is pressed.
When the home icon beside the SearchView
is pressed.
I want it to lose focus (and hence collapse) if the user clicks not only on these two things, but anywhere else on the screen (e.g., any button or any blank portion of the screen without a view on it).
Well, I have another simpler and tidier way of doing this. If you're using search widget as an action view in the toolbar (https://developer.android.com/guide/topics/search/search-dialog#UsingSearchWidget), you might want to make the SearchView lose focus and hide the keyboard when user touches anywhere else on the screen.
Instead of iterating and setting up touch listeners on every view in the hierarchy except the SearhView, you can simply make use of this solution since the SearchView has a AutoCompleteTextView in it.
Step 1: Make the parent view(content view of your activity) clickable and focusable by adding the following attribute
android:clickable="true"
android:focusableInTouchMode="true"
Step 2: Set OnFocusChangeListener on the SearchView AutoCompleteTextView
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
final MenuItem search = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) search.getActionView();
// get a reference of the AutoCompleteTextView from the searchView
AutoCompleteTextView searchSrcText = searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
searchSrcText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
});
return super.onCreateOptionsMenu(menu);
}
That's it! Hopefully this is useful for future readers :)
Well I found out the following solution. I used setOnTouchListener on every view that is not an instance of searchview to collapse the searchview. It worked perfect for me. Following is the code.
public void setupUI(View view) {
if(!(view instanceof SearchView)) {
view.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
searchMenuItem.collapseActionView();
return false;
}
});
}
//If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView);
}
}
}
This is the answer I referred to.
in my case, i had to stop the search and close the keyboard, whenever user clicks on any other view, this worked for me.
public static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View view = getCurrentFocus();
if (view != null && view instanceof EditText) {
Rect r = new Rect();
view.getGlobalVisibleRect(r);
int rawX = (int) ev.getRawX();
int rawY = (int) ev.getRawY();
if (!r.contains(rawX, rawY)) {
hideSoftKeyboard(MainActivity.this);
}
}
}
return super.dispatchTouchEvent(ev);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With