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!
Related
I am having Viewpager with 3 fragments. I want to show menu in only one of the fragments.
1st, I don't know why toolbar.inflateMenu doesn't work.
2nd, the menu works, if I have onPrepareOptionsMenu method and do
getMenuInflater().inflate(R.menu.add_user, menu); but the menu is displayed in all the fragments.
So, according to other questions in stack overflow, I implemented the below code, but it doesn't show the menu, it enters the method but menu is not shown.
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
//getMenuInflater().inflate(R.menu.add_user, menu);
info("Menu=>${tabs_viewpager.currentItem}")
val menuItem = menu?.findItem(R.id.addUserMenu)
menuItem?.setVisible(tabs_viewpager.currentItem == 1)
return true
}
The control comes to this method and shows currentItem. But it doesn't display the menu. Menu is there with id. Can someone direct me what can I correct to get this work?
try calling setHasOptionsMenu(true); in oncreate() of the fragments where you want the menu to show (you can set it to false in the fragments where you do not want the menu to show).
also include:
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
// your code
}
in the fragments where you want to set/change the menu. this is called everytime before the menu is shown.
you can also call invalidateOptionsMenu() or supportInvalidateOptionsMenu() (if you're using the support library) to force onPrepareOptionsMenu(menu) to be called.
you may want to check out this menus tutorial
good luck
clive
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.
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);
}
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.
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.