How to close a SearchView programmatically on back pressed? - android

I have the same question which I found here which I will re-iterate because the solution is not 100% exactly what I need:
I currently have a SearchView in the action bar of my app. When I click the search icon, the SearchView expands and the keyboard pops up as expected. Clicking the "X" in the SearchView box closes the SearchView as expected. However, when the SearchView is activated and I press the "back" button, my app is exited. This is the correct behavior, but what I am trying to do now is to capture back button press and just have it close the SearchView (not my app) when the SearchView is visible. Is there a way to invoke the SearchView OnCloseListener() programmatically on a back button press? For example, something like this:
Here is the solution:
#Override
public void onBackPressed() {
if (!searchView.isIconified()) {
searchView.setIconified(true);
} else {
super.onBackPressed();
}
}
The problem is the solution requires the user to press back not once, but twice: once* to exit the keyboard and **once to close the SearchView.
How can I close the keyboard AND the SearchView at the same time by pressing back once?
edit:
Somone had a similar problem with EditText and the solution was to subclass the EditText view.

#Override
public void onBackPressed() {
if (!searchView.isIconified()) {
searchView.setIconified(true);
searchView.onActionViewCollapsed()
} else {
super.onBackPressed();
}
}
below method is Clear your text Only
searchView.setIconified(true);
below This methods is close your search view
searchView.onActionViewCollapsed()

try
#Override
public void onBackPressed() {
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
if (!searchView.isIconified()) {
searchView.setIconified(true);
} else {
super.onBackPressed();
}
}

Add a method to close the keyboard within onBackPressed()
here is the code to hide keyboard.
private void hideKeyboard() {
InputMethodManager imm = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mInputField.getWindowToken(), 0);
}

Based on #Archana answer, the onBackPressed() should be like :
#Override
public void onBackPressed() {
hideSoftKeyboard();
if (!searchView.isIconified()) {
searchView.setIconified(true);
} else {
super.onBackPressed();
}
}
private void hideSoftKeyboard(){
View view = activity.getCurrentFocus ();
if (view != null) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService (Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow (view.getWindowToken (), 0);
}
}
or you can also override the onKeyDown()
#Override
public boolean onKeyDown (int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
hideSoftKeyboard ();
if (! searchView.isIconified ()) {
searchView.setIconified (true);
}
return true;
}
return super.onKeyDown (keyCode, event);
}
private void hideSoftKeyboard() {
View view = activity.getCurrentFocus ();
if (view != null) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService (Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow (view.getWindowToken (), 0);
}
}

An interesting answer!
#Override
public void onBackPressed() {
if (!searchView.isIconified()) {
searchView.setIconified(true);
searchView.setIconified(true);
} else {
super.onBackPressed();
}
}

public class MainActivity extends AppCompatActivity {
MenuItem menuItemSearch;
#Override
protected void onResume() {
if(menuItemSearch!=null)
MenuItemCompat.collapseActionView(menuItemSearch); // while activity begins, searchView is closed if remained open.
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menuItemSearch = menu.findItem(R.id.menuSearch);
}
}

I did it like this in the activity where the SearchView is located
#Override
public void onBackPressed() {
super.onBackPressed();
if (!searchView.isIconified()) {
searchView.setIconified(true);
}
}

Instead of hide soft keyboard manually, try clearFocus() method
mSearchView.setIconified(true);
mSearchView.clearFocus();

Related

hide keyboard from remote's back button in android TV Leanback

I was trying to hide the keyboard when the back button is pressed but its actually going back to previous menu when the back button is pressed. What I have is a simple activity with SupportSearchFragment.
public class SearchActivity extends LeanbackActivity {
private SearchFragment mFragment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
mFragment = (SearchFragment) getSupportFragmentManager()
.findFragmentById(R.id.search_fragment);
}
#Override
public boolean onSearchRequested() {
mFragment.startRecognition();
return true;
}
}
The fragment is
public class SearchFragment extends SearchSupportFragment
implements SearchSupportFragment.SearchResultProvider {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setSearchResultProvider(this);
}
#Override
public ObjectAdapter getResultsAdapter() {
return null;
}
#Override
public boolean onQueryTextChange(String newQuery) {
loadQuery(newQuery);
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
loadQuery(query);
return true;
}
}
What I am looking for is, once the back button is pressed, it should hide the keyboard and then another press of back button, it should go to the previous menu.
What I have found is if the ArrayObjectAdapter has any items to show, then back button directly takes to the previous menu. However, if there is no item, it hides the keyboard.
Any suggestion? Thanks in Advance.
First override onBackPressed ,ref
override fun onBackPressed(){
if( view.keyboardIsVisible() )
this.hideKeyboard()
else
super.onBackPressed(); // optional depending on your needs
}
Implement your KeyIsVisible() , ref
fun View.keyboardIsVisible() = WindowInsetsCompat
.toWindowInsetsCompat(rootWindowInsets)
.isVisible(WindowInsetsCompat.Type.ime())
and Hide Keyboard by
/**
* Use only from Activities, don't use from Fragment (with getActivity) or from Dialog/DialogFragment
*/
fun Activity.hideKeyboard() {
val imm = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
val view = currentFocus ?: View(this)
imm.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
Ps , It was too late when I saw your language is java , I have attached refs which will help you converting .
Thanks #Anshul for your answer. I will just what I exactly needed because the back button always hides the keyboard.
in Activity
override fun onBackPressed() {
if (fragment?.isKeyBoardVisible() != true) super.onBackPressed()
}
in fragment
fun isKeyBoardVisible() = ViewCompat.getRootWindowInsets(requireView())?.isVisible(WindowInsetsCompat.Type.ime()) ?: true

How to hide soft keyboard without losing focus on searchview

Expand searchview when fragment is oppened , request focus on searchview but hide soft keyboard .
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.barcode,menu);
MenuItem scan = menu.findItem(R.id.scanbarcode);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem scan = menu.findItem(R.id.scanbarcode);
mBarcode = (android.support.v7.widget.SearchView) scan.getActionView();
mBarcode.setQueryHint(getString(R.string.scanb));
scan.expandActionView();
mBarcode.setOnQueryTextListener(this);
}
write this in your activity in manifest file
android:windowSoftInputMode="stateHidden|adjustResize"
and in your fragment rite this
searchTditText.requestFocus();
Call this method to hide soft keyboard.
public static void hideSoftKeyboard(Context context, View view) {
if (view != null) {
InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
Check this code:
// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm =
(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Keyboard remain opens when Toolbar back arrow is pressed

I am following below code:-
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle arrow click here
if (item.getItemId() == android.R.id.home) {
finish();
overridePendingTransition(R.transition.right_in, R.transition.right_out);
}
return super.onOptionsItemSelected(item);
}
In this when my keyboard is open and I press my toolbar back arrrow ,the keyboard remain open and activity got finish. I have tried forcefully hiding keyboard in on pause() by callling below method but doesn't look good while transition :-
public static void hideKeyboard(Activity activity) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
//Find the currently focused view, so we can grab the correct window token from it.
View view = activity.getCurrentFocus();
//If no view currently has focus, create a new one, just so we can grab a window token from it
if (view == null) {
view = new View(activity);
}
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
Try to put in your toolbar back button this code:
//Hide keyboard when button was clicked.
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
like this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle arrow click here
if (item.getItemId() == android.R.id.home) {
finish();
overridePendingTransition(R.transition.right_in, R.transition.right_out);
}
//Hide keyboard when button was clicked.
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
return super.onOptionsItemSelected(item);
}
Why are you getting android home button with onOptionsItemSelected() ?
Just do like above :
toolbar.setNavigationOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
main = new Intent(SettingActivity.this, MainActivity.class);
main.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
finish();
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
startActivity(main);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
});
Hope it will help you, Darkball60

The override method onBackPressed doesn't work when showing popup window

I want to handle the back press event when showing a popup window in android.
I do like this.
In the fragment:
#Override
public boolean onBackPressed() {
if (backPressStrategy == BACK_PRESS_PLAN_A) {
if (guideDialog != null) {
guideDialog.dismiss();
}
closeFlashPay(REQ_CLOSE_FLASH_PAY_AND_FINISH);
return true;
} else if (backPressStrategy == BACK_PRESS_PLAN_B) {
if (guideDialog != null) {
guideDialog.dismiss();
}
getActivity().finish();
return true;
} else {
return false;
}
}
And in the Activity, I do like this
#Override
public void onBackPressed() {
PayBaseFragment contentFragment = (PayBaseFragment) getSupportFragmentManager().findFragmentByTag(TAG_CONTENT_FRAGMENT);
if (contentFragment != null && contentFragment.onBackPressed()) {
return;
}
super.onBackPressed();
}
The problem is, the first time when I pressed back button, the popupwindow just disappeared and the override onBackPressed method was not invoked. Unless I press back button two times.
I show my popup window like this
guideDialog.showAtLocation(getActivity().getWindow().getDecorView(), Gravity.CENTER, 0, 0);
Thanks for help
You need to handle the back button key of your dialog with this :
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
#Override
public boolean onKey(DialogInterface arg0, int keyCode,
KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
dialog.dismiss();
// you can call your onBackPress here
}
return true;
}
});

How to dismiss keyboard in Android SearchView?

I have a searchView in the ActionBar. I want to dismiss the keyboard when the user is done with input. I have the following queryTextListener on the searchView
final SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextChange(String newText) {
// Do something
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
showProgress();
// Do stuff, make async call
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
return true;
}
};
Based on similar questions, the following code should dismiss the keyboard, but it doesn't work in this case:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
I've also tried:
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
Neither one works. I'm not sure if this is a Honeycomb specific problem or if it's related to the searchView in the ActionBar, or both. Has anyone gotten this working or know why it does not work?
I was trying to do something similar. I needed to launch the SearchActivity from another Activity and have the search term appear on the opened search field when it loaded. I tried all the approaches above but finally (similar to Ridcully's answer above) I set a variable to SearchView in onCreateOptionsMenu() and then in onQueryTextSubmit() called clearFocus() on the SearchView when the user submitted a new search:
private SearchView searchView;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_menu, menu);
searchView = (SearchView) menu.findItem(R.id.menu_search)
.getActionView(); // set the reference to the searchView
searchView.setOnQueryTextListener(this);
searchMenuItem = (MenuItem) menu.findItem(R.id.menu_search);
searchMenuItem.expandActionView(); // expand the search action item automatically
searchView.setQuery("<put your search term here>", false); // fill in the search term by default
searchView.clearFocus(); // close the keyboard on load
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
performNewSearch(query);
searchView.clearFocus();
return true;
}
Simple, straight to the point and clean:
#Override
public boolean onQueryTextSubmit(String query) {
// your search methods
searchView.clearFocus();
return true;
}
just return false on onQueryTextSubmit just like below
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
Somehow it works if you call
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
and then
otherWidget.requestFocus();
For me, none of the above was working on the first submit. It was hiding and then immediately re-showing the keyboard. I had to post the clearFocus() on the view's handler to make it happen after it was done with everything else.
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
if (!"".equals(query)) {
mSearchView.post(new Runnable() {
#Override
public void run() {
mSearchView.clearFocus();
}
});
}
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
For me, the following works:
In my activity I have a member variable
private SearchView mSearchView;
In onCreateOptionsMenu() I set that variable like so:
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.library, menu);
mSearchView = (SearchView)menu.findItem(R.id.miSearch).getActionView();
mSearchView.setOnQueryTextListener(this);
return true;
}
In the QueryTextListener at last, I do this:
mSearchView.setQuery("", false);
mSearchView.setIconified(true);
I had a look at the source code of SearchView, and if you do not reset the query text to an empty string, the SearchView just does that, and does not remove the keyboard neither. Actually, drilling down deep enough in the source code, it comes to the same, yuku suggested, but still I like my solution better, as I do not have to mess around with those low level stuff.
Edit: I added the better solution on top, but also kept the old answer as a reference.
#Override
public boolean onQueryTextSubmit(String query) {
searchView.clearFocus();
return false;
}
Original Answer: I programmed using a setOnQueryTextListener. When the searchview is hidden the keyboard goes away and then when it is visible again the keyboard does not pop back up.
//set query change listener
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
#Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onQueryTextSubmit(String query) {
/**
* hides and then unhides search tab to make sure keyboard disappears when query is submitted
*/
searchView.setVisibility(View.INVISIBLE);
searchView.setVisibility(View.VISIBLE);
return false;
}
});
if someone is looking how to collpase searchView/keyboard, use below code
/*
setup close button listener
*/
searchView.findViewById<ImageView>(R.id.search_close_btn).setOnClickListener {
adapter.filter(null)//reset default list
searchView.onActionViewCollapsed() //collapse SearchView/Keyboard
true
}
/*
setup text change listener
*/
searchView.setOnQueryTextListener(object:SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(query: String?): Boolean {
adapter.filter(if(query.isNullOrEmpty()) "" else query)
searchView.onActionViewCollapsed() //collapse SearchView/Keyboard
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
adapter.filter(if(newText.isNullOrEmpty()) "" else newText)
return true
}
})
In a tablet app I'm working on with a dual pane activity, I've wrote only
f.getView().requestFocus(); // f is the target fragment for the search
and that was enough to dismiss the soft keyboard after a search. No need to use InputMethodManager
I used ActionBarSherlock 4.3 and I have a ProgressDialog. When I dismiss it in postExecute method, Searchview gain focus. To fix that:
//Handle intent and hide soft keyboard
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
searchView.setQuery("", false);
searchView.setIconified(true);
searchView.clearFocus();
}
/*When dismiss ProgressDialog, searchview gain focus again and shows the keyboard. I call clearFocus() to avoid it.*/
AsyncTask.onPostExecute(){
if(pd!=null)
pd.dismiss();
if(searchView!=null)
searchView.clearFocus();
}
Hope it helps.
You can use it.
if (isKeybordShowing(MainActivity.this, MainActivity.this.getCurrentFocus())) {
onBackPressed();
}
public boolean isKeybordShowing(Context context, View view) {
try {
InputMethodManager keyboard = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.hideSoftInputFromWindow(view.getWindowToken(), 0);
return keyboard.isActive();
} catch (Exception ex) {
Log.e("keyboardHide", "cannot hide keyboard", ex);
return false;
}
}
Two solutions that worked for me, the first one using the SearchView instance:
private void hideKeyboard(){
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
}
Second solution:
private void hideKeyboard(){
InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
Below Code is working for me to hide keyboard in Searchview
MenuItem searchItem = baseMenu.findItem(R.id.menuSearch);
edtSearch= (EditText) searchItem.getActionView().findViewById(R.id.search_src_text);
MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
edtSearch.post(new Runnable() {
#Override
public void run() {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(searchEditText.getWindowToken(), 0);
}
});
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
return true;
}
});
Why dont you try this? When you touch the X button, you trigger a focus on the searchview no matter what.
ImageView closeButton = (ImageView)searchView.findViewById(R.id.search_close_btn);
closeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText et = (EditText) findViewById(R.id.search_src_text);
et.setText("");`enter code here`
searchView.setQuery("", false);
searchView.onActionViewCollapsed();
menuSearch.collapseActionView();
}
});
fun View.hideKeyboard() {
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(windowToken, 0)
}
#Override
public void onResume() {
super.onResume();
searchView.clearFocus();
}
I tried all the answers above but none worked, clearing focus onResume worked for me

Categories

Resources