I have implemented searchview in actionbar and it is working fine. In viewpager if user switch between fragment I want to keep the state of searchview, to do so whenever fragment switch I applied query and show search result in recycler until now it is working like charm except I want to expand my searchview and put a query into it on fragment change method. I have seen lots of thread on it and I have applied multiple solutions none worked.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_search"
android:icon="#drawable/ic_search_black_24dp"
app:showAsAction="always|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"
android:title="Search"/>
</menu>
In onCreateOptionsMenu i am inflating my menu.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main2, menu);
this.menu = menu;
searchActionBar(menu);
super.onCreateOptionsMenu(menu, inflater);
}
In search Actionbar i am fetching query result and save query text to mQuery and clear this text when searchview collapse.
private void searchActionBar(Menu menu){
searchViewItem = menu.findItem(R.id.action_search);
searchViewAndroidActionBar = (SearchView) MenuItemCompat.getActionView(searchViewItem);
searchViewAndroidActionBar.setIconifiedByDefault(false);
searchViewAndroidActionBar.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#SuppressLint("RestrictedApi")
#Override
public boolean onQueryTextSubmit(String query) {
searchViewAndroidActionBar.clearFocus();
mQuery = query;
fetchSearchResult(query);
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
MenuItemCompat.setOnActionExpandListener(searchViewItem, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
mQuery="";
return true;
}
});
}
This function is called when fragment switch in viewpager , if there is any query I want to set in searchview. But searchview doesn't expand. Although query submit function is running.
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isResumed() && isVisibleToUser) {
if (searchViewAndroidActionBar != null) {
searchViewAndroidActionBar.setFocusable(true);
searchViewAndroidActionBar.setQuery(mQuery,true);
}
}
}
Any help would be appreciated.
I want to add a searchview and checkbox into action bar menu. And this checkbox will be visible if searchview is opened. And in it's opposite case it will be hidden. How I can do this?
I do something below . But it doesnt work correctly. I want hide checkbox (In my notes) when searchview is closed.
menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/search_button"
android:icon="#drawable/ic_icon_search"
android:title="Arama"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView">
</item>
<item
android:id="#+id/search_in_my_notes_checkbox"
app:showAsAction="ifRoom"
android:title="#string/search_in_my_notes"
android:checkable="true"
android:visible="false"
/>
</menu>
HomeActivity.java
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.search_button){
MenuItem searchInMyNotesCheckbox = (MenuItem)menu.findItem(R.id.search_in_my_notes_checkbox);
searchInMyNotesCheckbox.setVisible(true);
}
return super.onOptionsItemSelected(item);
}
I found an alternative solution. I will use two checkbox image with checked and unchecked. And I will override onCreateOptionsMenu like this :
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
this.menu = menu;
getMenuInflater().inflate(R.menu.menu, menu);
MenuItem search = (MenuItem)menu.findItem(R.id.search_button2);
final MenuItem searchInMyNotesCheckbox = (MenuItem) menu.findItem(R.id.search_in_my_notes_checkbox);
MenuItemCompat.setOnActionExpandListener(search,
new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem menuItem) {
// Return true to allow the action view to expand
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem menuItem) {
MenuItem searchInMyNotesCheckbox = (MenuItem) menu.findItem(R.id.search_in_my_notes_checkbox);
searchInMyNotesCheckbox.setVisible(false);
return true;
}
});
searchInMyNotesCheckbox.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
if(item.getIcon() == R.drawable.checked_checkbox){
item.setIcon(R.drawable.unchecked_checkbox);
}
else {
item.setIcon(R.drawable.checked_checkbox);
}
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
Does anyone know how to hide the back button in AppCompat v21 searchview? (outlined by green line)
I've searched a lot but couldn't find anything useful.
menu_main.xml:
<item android:id="#+id/search"
android:title="#string/search_title"
app:showAsAction="always|collapseActionView"
android:icon="#drawable/abc_ic_search_api_mtrl_alpha"
android:orderInCategory="300"
app:actionViewClass="android.support.v7.widget.SearchView" />
<item android:id="#+id/action_home"
android:title="Home"
android:icon="#drawable/v_home"
app:showAsAction="always"
android:orderInCategory="180"/>
<item android:id="#+id/action_favorites"
android:title="Favorites"
android:icon="#drawable/v_favorites"
app:showAsAction="always" />
MainActivity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
firstMenu = menu;
searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
MenuItem searchItem = menu.findItem(R.id.search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setSubmitButtonEnabled(true);
searchView.setActivated(true);
searchView.setOnSearchClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
menuItemsVisibility(false);
}
});
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
#Override
public boolean onClose() {
menuItemsVisibility(true);
return false;
}
});
return true;
}
#Override
public void onBackPressed() {
menuItemsVisibility(true);
super.onBackPressed();
}
// setting visibility of menu items on search
private void menuItemsVisibility(boolean visibility) {
MenuItem homeItem = firstMenu.findItem(R.id.action_home);
MenuItem favoriteItem = firstMenu.findItem(R.id.action_favorites);
MenuItem otItem = firstMenu.findItem(R.id.action_ot);
MenuItem ntItem = firstMenu.findItem(R.id.action_nt);
homeItem.setVisible(visibility);
favoriteItem.setVisible(visibility);
otItem.setVisible(visibility);
ntItem.setVisible(visibility);
}
Note: the behavior showAsAction:Always and using methods menuItemsVisibility() to adjust the visibility of toolbar items is intentional.
Another Note: MainActivity extends ActionBarActivity and it also implements implements ObservableScrollViewCallbacks from ObservableScrollView Library.
changed app:showAsAction="always|collapseActionView" to app:showAsAction="always"
Use the method:
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
in order to remove the home button from the action bar.
It's not perfectly safe method because back button (navigation up) doesn't have id. But if you are using AppCompat with Toolbar, you can use this code to find it. It should be the first in the layout.
int count = this.getToolbar().getChildCount();
for(int i = 0; i < count; ++i) {
View v = this.getToolbar().getChildAt(i);
if(v instanceof ImageButton) {
return (ImageButton)v;
}
}
Call this method inside onPrepareOptionsMenu if you want to change drawable of that button.
I used SherlockActionBar for my ActionBar, but I want to use AppCompact for my search view. To change my code from sherlock to AppCompact, I wrote this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
// SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
//searchView.setOnQueryTextListener(this);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
#Override
public boolean onQueryTextChange(String s) {
return false;
}
});
return true;
// return super.onCreateOptionsMenu(menu);
}
xml menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item
android:id="#+id/action_search"
android:actionViewClass="android.support.v7.widget.SearchView"
android:icon="#android:drawable/ic_menu_search"
android:title="action_search"
app:showAsAction="always|collapseActionView" />
</menu>
but it crashed. How can I fix it?
EDIT:
change android:actionViewClass to app:actionViewClass
Background
I have a searchView being initialized using a special class I've made, that's being used across all of the activities and fragments.
The problem
Recently, probably due to updates to the support library (or because I didn't use it so far, I don't remember), I can't catch events of expand/collapse of the searchView.
As I've found, this happens even if I use setSupportActionBar with a Toolbar instance.
What I've tried
I've tried using each of the next methods, but none worked:
MenuItemCompat.setOnActionExpandListener.
MenuItemCompat.setOnActionExpandListener together with iconifying the SearchView, as suggested on some websites.
setOnActionExpandListener on the search menu item itself, but then it crashes since it can't be used when extending the ActionBarActivity.
SearchView.setOnCloseListener , but this works only if I close it, and only using the UI (doesn't get called when calling collapseActionView ).
I've also tried to mess around with the XML file of the search menu item.
The code
Here's the helper class I've made:
SearchHolderCompat
public class SearchHolderCompat {
public MenuItem mSearchMenuItem;
public SearchView mSearchView;
private final Activity _context;
public SearchHolderCompat(final Activity context) {
_context = context;
}
public boolean isCurrentyExpanded() {
return mSearchMenuItem != null && MenuItemCompat.isActionViewExpanded(mSearchMenuItem);
}
public boolean hasQuery() {
return mSearchMenuItem != null && mSearchView != null && MenuItemCompat.isActionViewExpanded(mSearchMenuItem)
&& !TextUtils.isEmpty(mSearchView.getQuery());
}
public void addSearchItemAndInit(final Menu menu, final OnQueryTextListener onQueryTextListener,
final OnActionExpandListener onActionExpandListener) {
final MenuInflater menuInflater = _context.getMenuInflater();
menuInflater.inflate(R.menu.search_menu_item, menu);
init(menu.findItem(R.id.menuItem_search), onQueryTextListener, onActionExpandListener);
}
public void init(final MenuItem searchMenuItem, final OnQueryTextListener onQueryTextListener,
final OnActionExpandListener onActionExpandListener) {
this.mSearchMenuItem = searchMenuItem;
mSearchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
if (mSearchView == null) {
MenuItemCompat.setShowAsAction(searchMenuItem, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
| MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
MenuItemCompat.setActionView(searchMenuItem, mSearchView = new SearchView(_context));
}
mSearchView.setQueryHint(_context.getString(R.string.search));
mSearchView.setOnQueryTextListener(onQueryTextListener);
MenuItemCompat.setOnActionExpandListener(searchMenuItem, onActionExpandListener);
}
}
MainActivity.java
public class MainActivity extends ActionBarActivity {
SearchHolderCompat mSearchHolder = new SearchHolderCompat(this);
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
mSearchHolder.addSearchItemAndInit(menu, new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(final String arg0) {
android.util.Log.d("AppLog", "onQueryTextSubmit");
return false;
}
#Override
public boolean onQueryTextChange(final String queryText) {
android.util.Log.d("AppLog", "onQueryTextChange");
return true;
}
}, new OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(final MenuItem arg0) {
android.util.Log.d("AppLog", "onMenuItemActionExpand");
return false;
}
#Override
public boolean onMenuItemActionCollapse(final MenuItem arg0) {
android.util.Log.d("AppLog", "onMenuItemActionCollapse");
return false;
}
});
return true;
}
}
search_menu_item.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<!-- search items -->
<item
android:id="#+id/menuItem_search"
android:icon="#drawable/ic_action_search"
android:title="#string/search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"
tools:ignore="AlwaysShowAction"/>
</menu>
The question
What's the correct way to handle the SearchView and the search menu item (using the support library) ?
How come "MenuItemCompat.setOnActionExpandListener" doesn't work?
After looking for a solution for couple of hours I've implement something like this. and worked for me. (I wanted Expand and Collapse events anyhow)
.
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
if(searchItem != null)
{
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
// use this method for search process
searchView.setOnSearchClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//Search view is expanded
showSearchPage();
}
});
searchView.setOnCloseListener(new SearchView.OnCloseListener()
{
#Override
public boolean onClose()
{
//Search View is collapsed
hideSearchPage();
return false;
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
{
#Override
public boolean onQueryTextSubmit(String query)
{
// use this method when query submitted
Toast.makeText(MainActivity.this, query, Toast.LENGTH_SHORT).show();
return false;
}
#Override
public boolean onQueryTextChange(String newText)
{
// use this method for auto complete search process
Log.e("SearchValueIs",":"+newText);
return false;
}
});
}
return super.onCreateOptionsMenu(menu);
}
Hope It will help Someone...
Android training
app:showAsAction="ifRoom|collapseActionView"
You can add ViewTreeObserver to track the visibility state of android.support.v7.appcompat.R.id.search_edit_frame. You can check my answer here: https://stackoverflow.com/a/28762632/1633609
You can see below how to handle Expand and Collapsed states!
To answer why MenuItemCompat.setOnActionExpandListener(...) is not working, this listener is only called if the showAsAction of the SearchView is set to MenuItemCompat.SHOW_AS_ACTION_ALWAYS (you can also add more options).
This is the copy of my answer form the other question:
I found that MenuItemCompat.setOnActionExpandListener(...) is not working if you don't pass:
searchItem
.setShowAsAction(MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
| MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
But this is changing the SearchView and is replacing the DrawerToggle with back arrow.
I wanted to keep the original views and still track the Expanded/Collapsed state and use supported Search View.
Solution:
When android.support.v7.widget.SearchView is changing the view state the LinearLayout view's, with id android.support.v7.appcompat.R.id.search_edit_frame, visibility value is being changed from View.VISIBLE to View.GONE and opposite. So I add ViewTreeObserver to track the visibility change of the search edit frame.
menu_search.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/action_search"
android:icon="#android:drawable/ic_menu_search"
android:title="#string/search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"/>
</menu>
In the activity:
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuItem;
..........
private View mSearchEditFrame;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_search, menu);
MenuItem searchItem = (MenuItem) menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat
.getActionView(searchItem);
searchView.setSubmitButtonEnabled(false);
mSearchEditFrame = searchView
.findViewById(android.support.v7.appcompat.R.id.search_edit_frame);
ViewTreeObserver vto = mSearchEditFrame.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
int oldVisibility = -1;
#Override
public void onGlobalLayout() {
int currentVisibility = mSearchEditFrame.getVisibility();
if (currentVisibility != oldVisibility) {
if (currentVisibility == View.VISIBLE) {
Log.v(TAG, "EXPANDED");
} else {
Log.v(TAG, "COLLAPSED");
}
oldVisibility = currentVisibility;
}
}
});
return super.onCreateOptionsMenu(menu);
}
I know I'm very late to post this answer but hope it helps someone else. I recently came across the issue and I just made the Override methods return true and it worked like a charm.
#Override
public boolean onMenuItemActionExpand(final MenuItem arg0) {
android.util.Log.d("AppLog", "onMenuItemActionExpand");
return true;
}
#Override
public boolean onMenuItemActionCollapse(final MenuItem arg0) {
android.util.Log.d("AppLog", "onMenuItemActionCollapse");
return true;
}
In more recent versions
menuSearch.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
//SearchView appers
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
//SearchView disappears
return true;
}
});