Android: callback for search widget opened and dismissed - android

I have a screen layout that is forced to be potrait mode. Because it is very complex I don't have the time right now to invest creating a separate one for landscape mode. It also doesn't make much sense for my type of application.
However, for input fields it's better to provide a landscape mode, because some phones have a hardware keyboard, which automatically aligns the phone in landscape and therefor makes it hard to look at the app that is still in portrait mode.
My solution to this is to put all text input into a dialog and temporarily enable landscape mode (if requested by the user) until the dialog is dismissed again.
This works perfectly. Except of the overlaying search widget (when pressing the search button from my application). I'm looking for two callbacks: one, when the search widget is raised (I cannot listen to the search button, because I sometimes raise it manually via a soft button) and when it is dismissed again (regardless if the search was finally triggered or canceled - it needs to work for both cases).
Any suggestions?

There is an Activity callback for when search is activated. onSearchRequested()
For the dismiss/cancel of the search widget, you can add listeners via the SearchManager:
SearchManager.OnCancelListener
SearchManager.OnDismissListener
Get a reference to your SearchManager with:
context.getSystemService(Context.SEARCH_SERVICE)
see getSystemService()

When using the Search Widget you can use the OnActionExpandListener on the associated action bars menu item. This also works great with the AppCompat Support Library for API versions below 14.
The OnActionExpandListener has two methods:
onMenuItemActionCollapse
onMenuItemActionExpand
See some code example below:
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
MenuItem searchItem = menu.findItem(R.id.action_search);
MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener(){
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
KLog.i(TAG, "onMenuItemActionCollapse");
return true;
}
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
KLog.i(TAG, "onMenuItemActionExpand");
return true;
}
});
mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
In case you do not use the Support Library use the OnActionExpandListener on the menu item directly.

Related

Android app giving I/InjectionManager? dispatchCreateOptionsMenu at screen

I am developing the app, when I am implementing the menu for my app, the I am hiding some menuitems from some screens and for this I am using this code :
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem search = menu.findItem(R.id.action_search);
search.setVisible(false);
MenuItem create_opportunity = menu.findItem(R.id.menu_example);
create_opportunity.setVisible(false);
//this.invalidateOptionsMenu();
return super.onPrepareOptionsMenu(menu);
}
When I am uncommenting this invalidatinoptionsmenu line , it starts giving I/InjectionManager? dispatchCreateOptionsMenu continously in the logs of the app. May i know due to this the battery also can be consumed ?? , this logs I am getting in samsung mobiles only.
Appreciate your inputs.
I'm working on a similar issue with my own app. The documentation pretty much says it all:
When an event occurs and you want to perform a menu update, you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().
so calling invalidateOptionsMenu() from onPrepareOptionsMenu will create an infinite loop.

Changing Action Bar Menu Tab Label

I want to change one of my Action Bar Menu Tab Labels depending on the state of a variable in my code. I found the following that describes how to use onPrepareMenuOptions() for this purpose, but my problem is that onPrepareMenuOptions() is being called after I change the variable that controls the label state.
How can I alter a MenuItem on the Options Menu on Android?
As specific as I can be, I have a dialogFragment that's brought up when the user selects the relevant Action Bar item. The dialog allows the user to change a parameter, and depending on value selected, I want to change the AB item label (but not the code associated with either the AB item or the dialogFragment it starts up.
Is there something I should be doing (perhaps in the dialog's onDismiss() method) to force my application to call onPrepareMenuOptions()??
In response to Nate's request, my activity has the following code:
public boolean onCreateOptionsMenu (Menu menu)
{
getMenuInflater().inflate (R.menu.app_menu, menu);
this.abMenu = menu;
this.varTab = abMenu.findItem (R.id.menu_varTab);
// Need to be able to change this label
return super.onCreateOptionsMenu (menu);
}
#Override
public boolean onPrepareOptionsMenu (Menu menu)
{
varTab.setTitle (0 == importantVariable
? ("Set Var")
: ("Set Var\n" + String.valueOf (importantVariable)) + " units");
return super.onPrepareOptionsMenu (menu);
}
Following good advice, I added act.invalidateOptionsMenu() to the onDismiss() method of the dialogFragment associated with this menu item, and now the onPrepareOptionsMenu() is called when it should.
On Android 2.3.x and lower, the system calls onPrepareOptionsMenu() each time the user opens the options menu (presses the Menu button).
On Android 3.0 and higher, the options menu is considered to always be open when menu items are presented in the action bar. When an event occurs and you want to perform a menu update, you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().
I believe - if you are using tabs in your action bar, that something like this should work:
bar.getTabAt(0).setText("Some new Sequence");

Actionbar Sherlock Search Widget expand does not work

I'm using Actionbar Sherlock. The activity be shown on startup should start in a "search mode" to start searching immediately. For doing so I use the following code:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
//collapse search
MenuItem searchItem = menu.add(Menu.NONE, R.string.inlineSearch, Menu.NONE, getString(R.string.inlineSearch)).setIcon(R.drawable.menu_search);
searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
searchView = new SearchView(this);
searchItem.setActionView(new SearchView(this));
searchItem.expandActionView();
return true;
}
The SearchView is the View provided by Android / Actionbar Sherlock.
The problem I'm facing with that is that no matter what I do, the item is never expanded on startup.
I tried calling the expandActionView method after startup by using another actionbar item, nothing changed.
I implemented my own View implementing CollapsibleActionView, but the methods onActionViewExpanded() and onActionViewCollapsed() never get called.
But if I click the collapsed button of the SearchView, the view expands as expected.
Does anyone know what I'm doing wrong? Thanks for your help!
After going through the source documentation I finally found the answer by myself.
menuItem.expandActionView() only takes effect if the MenuItem has set the following flag: searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
Hope that helps somebody out there!

Reset action bar after using SearchView

I'm using SearchView widget to enable searching in my app. After the initial click on the search icon, the SearchView widget expands into the search field and the "back" arrow is shown next to the application icon. If I click the application icon the action bar reverts to the initial state (no "back" arrow) and the SearchView reverts back to icon.
Now the problem: after the search is executed the action bar doesn't change, the only way to revert is to click the application icon or phone's "back" arrow. Not good since I want the action bar go to the initial state when the search is done. I tried SearchView.setIconofied(true) but there are 2 problems:
Search icon appears at the same spot as the edit field (originally it's on the far right).
Action bar still displays "back" arrow.
I think the problem I'm facing results from deviating from the regular navigation pattern. In my case everything is happening inside the same activity (search results are displayed in the same activity that hosts the action bar), so for example executing Activity.finish() simply makes app exit.
How do I trigger "go back one step" of the action bar? Or simulate click on the application icon?
It sounds like you've set this up as a collapsible action view on a MenuItem. You can call collapseActionView() on that MenuItem instance to send it back to its closed state.
the method collapseActionView() only works from API level 14. If you're looking to support for earlier versions of android, then you should use MenuItemCompat library.
Here's my solution to collapse the searchview and reset the action bar...
private MenuItem searchMenuItem;
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchMenuItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
customizeSearchView(searchView);
return super.onCreateOptionsMenu(menu);
}
#Override
protected void onNewIntent(Intent intent)
{
setIntent(intent);
if (searchMenuItem != null)
{
if (MenuItemCompat.expandActionView(searchMenuItem))
{
MenuItemCompat.collapseActionView(searchMenuItem);
}
else if (MenuItemCompat.collapseActionView(searchMenuItem))
{
MenuItemCompat.expandActionView(searchMenuItem);
}
}
handleIntent(intent);
}

SearchView focused when hiding the ActionBar menu

I have an ActionBar with a SearchView. The hidden/overflow menu items are shown on the right in a drop-down list when the menu button is selected. When the drop-down menu is hidden, the SearchView is focused and the keyboard shows. Is there a way to stop the keyboard from showing (except for the case where the SearchView is touched)?
Regards,
Julius.
Edit added code below:
Here is how I initialise it:
SearchManager searchManager = (SearchManager) mActivity.getSystemService(Context.SEARCH_SERVICE);
((SearchView) mSearchView).setSearchableInfo(searchManager.getSearchableInfo(mActivity.getComponentName()));
mSearchView.setIconifiedByDefault(mIconified);
mSearchView.setOnQueryTextListener(this);
mSearchView.setOnCloseListener(this);
mSearchView.setFocusable(false);
mSearchView.setFocusableInTouchMode(false);
if(null!=mQuery)
mSearchView.setQuery(mQuery, false);
Edit 2:
Here is what I do when the user wants to start the search:
#Override
public boolean onQueryTextSubmit(String query) {
// Hide keyboard
InputMethodManager imm = (InputMethodManager) mActivity.getSystemService(
FragmentActivity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearchView.getWindowToken(), 0);
...
mSearchView.setFocusable(false);
mSearchView.setFocusableInTouchMode(false);
return true;
}
try calling mSearchView.clearFocus() on your initialization of the searchView. That worked for me when I had a similar problem.
try call setFocusable(false) on SearchView when you init it.
I instantiated a search view when creating the options menu in a fragment and none of the above methods worked for me.
However, I was able to solve the problem by holding a reference to the SearchView, NOT setting the SearchView's iconified setting in onCreateOptionsMenu(), but setting it on a post when the fragment resumed like follows:
#Override
public void onResume() {
super.onResume();
getView().post(new Runnable() {
public void run() {
if (mFilterView.isIconfiedByDefault()) {
mFilterView.setIconifiedByDefault(false);
mFilterView.clearFocus();
}
}
});
}
Call requestFocus() for another view, ideally your results view, e.g.
_resultsFragment.getView().requestFocus();
I have just been pulling my hair out over the same issue.
I tried android:focusable="false". I tried the InputMethodManager. I tried creating a dummy view to take the focus but nothing worked.
I finally solved it with the following code inside onCreateOptionsMenu():
final ViewTreeObserver observer = mSearchView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
#Override
public void onGlobalLayout() {
observer.removeOnGlobalLayoutListener(this);
mSearchView.clearFocus();
}
});
The issue was that at every point in the Fragment's lifecycle the menu had not been created yet. The onCreateOptionsMenu() method was being called after onResume(), but only on some devices I tested on, which is really strange.
The above code makes sure that clearing the focus is done after any focus changes during creation of the page.
I hope this helps someone else, it would have saved me a lot of time to know this from the start.
When you set up your SearchView in your XML layout file (if you're using one), just use this:
android:focusable="false"
With this approach, your SearchView won't gain focus until you touch it...no matter where or if you "init" it in your code, or you hide your menu, or any other activity that might not have occurred in your debugging. This also eliminates the possible need to track where you are calling
setFocusable(false) //essentially does the same thing
in your code multiple times as the accepted answer suggests.

Categories

Resources