Reset action bar after using SearchView - android

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);
}

Related

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");

Android getActionBar() returns null when I touch hard menu button

I have action bar and menu located in action bar.
When I touch hard menu button getActionBar() returns null.
Third at the bottom is what I mean with hard menu button:
I can prevent app to crash as: if(getActionBar() != null) { // ... }
But it's not what I want to do. I need the action bar items to modification (add/remove). So I am not able to do while getActionBar() returns null.
Anyone has any idea why getActionBar() returns null?
UPDATE:
Here is my code:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (getActionBar() != null) { // Action bar is null here when I click hard menu button.
getActionBar().setDisplayHomeAsUpEnabled(true);
}
// Some logical operations here.
// Get the menu.
BaseActivity.menuOnActionBar = menu;
return super.onCreateOptionsMenu(menu);
}
In my activity, after refresh completes I remove action view (action view was set to xml right after refresh clicked in order to show progress bar):
menuOnActionBar.findItem(R.id.menu_refresh).setActionView(null); // This throws an error.
And menuOnActionBar variable definition in BaseActivity:
public static Menu menuOnActionBar;
Thrown error is: E/AndroidRuntime(4193): java.lang.NullPointerException
I need the action bar items to modification (add/remove).
First, you do not need an ActionBar instance for that, as you cannot affect action bar items through ActionBar anyway. If you are adding or removing action bar items, call invalidateOptionsMenu() on your Activity, which will force Android to call onCreateOptionsMenu() again.
More importantly, you should not be doing that as a result of a MENU press, as by then it is too late. Instead, call invalidateOptionsMenu() when something changes in the state of your application that requires a change in the mix of action bar items.
If you need to change something else about the action bar (e.g., tabs), that is where getActionBar() becomes more relevant. Two scenarios in which I know that getActionBar() will return null are:
You do not have an action bar
You are extending an ActionBarSherlock class (e.g., SherlockActivity), in which case you need to be calling getSupportActionBar()

How to intercept a click on the "Up" (home button) Button in ActionBarSherlock?

I have implemented a search feature for one of my project using ActionBar Sherlock. So now I have the search edit text on the ActionBar like in the samples of the official AB sherlock project repo (on github) : Collapsible action items
My search edit text is filtering a ListView within the activity. When the user starts to type in some characters, the ListView gets filtered. I did it by adding a textWatcher to the search Edit text like this :
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(Menu.NONE, SEARCH_ACTION_MENU, 0, "Search")
.setIcon(R.drawable.ic_search)
.setActionView(R.layout.search_edittext)
.setShowAsAction(
MenuItem.SHOW_AS_ACTION_ALWAYS
| MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
/** We get a reference to the search edit */
MenuItemWrapper menuItemWrapper = (MenuItemWrapper) menu.getItem(0);
final EditText searchEdit = (EditText) menuItemWrapper.getActionView();
/** We add a listener search filter listener */
searchEdit.addTextChangedListener(filterWatcher); // filterwatcher is a textWatcher
return true;
}
When I click on the search icon, the search Edit Text is shown and the user can start to type in things. Also, the home button is displayed as an "Up Home button" (with the left arrow).
Clicking on this arrow will make the search text view disappear but if the user has already started to type in things, the List View is filtered and is not reset when the search Text View is not visible anymore after the user clicks on the home "Up" button.
My question is : how can I intercept click on the "Up" button to reset my List View ? I think this is the only way I can reset my list.
I have already tried :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Log.d(Constants.LOG_TAG, "Home button clicked");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
It is not working when the "Home button" is displayed as "Up" button.
any help would be appreciated.
thanks in advance,
You need to implement CollapsibleActionView on your view in order to receive the onActionViewCollapsed() callback.
You should also upgrade to the version of ActionBarSherlock that is on the dev branch since it has crucial fixes for collapsible action items when used on the native action bar.
It should work with onOptionsItemSelected.
Make sure you are using com.actionbarsherlock.view.MenuItem.
You could also use onMenuItemSelected(int featureId, MenuItem item) in the same way.

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!

Android: callback for search widget opened and dismissed

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.

Categories

Resources