I\'m developing an app for Android 3.2 and greater with android-support-v4
. I need to implement OnActionExpandListener
for \"intercept\" when Searc
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);
}
Thanks!
For MenuItemCompat.setOnActionExpandListener to work you should add "collapseActionView" added in the menu item - for example -
<item android:id="@+id/action_search"
android:icon="@drawable/ic_action_search"
android:title="@string/action_search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView" />
And in the onCreateOptionsMenu you can use it this way -
MenuItemCompat.setOnActionExpandListener(menu_search,
new OnActionExpandListener()
{
@Override
public boolean onMenuItemActionCollapse(MenuItem item)
{
// Do something when collapsed
return true; // Return true to collapse action view
}
@Override
public boolean onMenuItemActionExpand(MenuItem item)
{
// Do something when expanded
return true; // Return true to expand action view
}
});
Your Listener should be MenuItemCompat.OnActionExpandListener() .
MenuItemCompat.setOnActionExpandListener(searchItem,
new MenuItemCompat.OnActionExpandListener() {
}
thanks for your help, your solution is work for me. and i'd like to vote you up, but i just realized i have only 1 reputation,(;′⌒`)
actually, my solution is similar to your, there is just one different in the menu xml file like this:
<item
android:id="@+id/apps_menu_search"
android:icon="@drawable/ic_action_search"
android:title="@string/apps_menu_search"
android:visible="true"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView" />
You probably missed the fact (like I did) that `MenuItemCompat.OnActionExpandListener' interface has a static implementation, and is not an instance method.
So, if you have a class that implements MenuItemCompat.OnActionExpandListener
then in that class you need to install it as the listener like this:
MenuItem menuItem = menu.findItem(R.id.search);
if (menuItem != null) {
MenuItemCompat.setOnActionExpandListener(menuItem,this);
MenuItemCompat.setActionView(menuItem, mSearchView);
}
The same paradigm applies to setActionView ... rather than invoke menuItem.setActionView(this)
, you pass the menuItem as the first argument to the static version MenuItemCompat.setActionView
and follow with the other argument(s).