Android ActionBar: collapsible SearchView with action button
Solution 1
After considering the suggestions from comments, many googling and testing succeeded in obtaining the desired effect. I'm not proud of this solution but it works, it's not too complicated and should be enough for this case.
In resume what I did:
- Placed
SearchView
with custom "add item" button incustomView
ofActionBar
. - Removed
collapseActionView
andandroid:actionLayout
from search item inmenu.xml
- Collapsing/expanding
SearchView
programmatically.
Some code to better understand what I did. Maybe this can be useful for someone.
menu.xml
<item
android:id="@+id/menu_search"
android:icon="@drawable/action_search"
android:showAsAction="always"
android:title="@string/search" />
// ... other menu items
actionbar_search.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="right"
android:orientation="horizontal">
<com.actionbarsherlock.widget.SearchView
android:id="@+id/search_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:iconifiedByDefault="false"
android:queryHint="@string/search_hint"
android:visibility="invisible" />
<ImageButton
android:id="@+id/add_item"
android:layout_width="wrap_content"
android:layout_height="match_parent"
style="@style/Widget.Sherlock.ActionButton"
android:src="@drawable/content_new"
android:title="@string/add_item" />
</LinearLayout>
MainActivity.java
@Override
public void onCreate(Bundle savedInstanceState) {
// ...
actionBar.setCustomView(R.layout.actionbar_search);
actionBarCustomView = ab.getCustomView();
searchView = ((SearchView) actionBarCustomView.findViewById(R.id.search_view));
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
searchView.setVisibility(View.INVISIBLE);
return false;
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// ...
case R.id.menu_search:
if (searchView.getVisibility() == View.VISIBLE) {
searchView.setIconified(true);
searchView.setVisibility(View.INVISIBLE);
} else {
searchView.setMaxWidth(abCustomView.getWidth() - addButton.getWidth());
searchView.setVisibility(View.VISIBLE);
searchView.setIconified(false);
}
break;
// ...
}
return true;
}
@Override
public void onBackPressed() {
if (searchView.getVisibility() == View.VISIBLE) {
searchView.setIconified(true);
searchView.setVisibility(View.INVISIBLE);
return;
}
// ...
}
Solution 2
You can do it only using yourmenu.xml.
Set your other menu icon to always show as an action. Your menu.xml should look like this:
<item
android:id="@+id/menu_search"
android:actionLayout="@layout/actionbar_search"
android:icon="@drawable/action_search"
android:showAsAction="always|collapseActionView"
android:title="@string/search"
/>
<item
android:id="@+id/your_other_menu_id"
android:showAsAction="always"
android:icon="@android:drawable/your_other_menu_ic"
/>
Solution 3
Simply you can do it like this
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setIconified(true); //to be opened collapsed
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.action_search:
searchView.setIconified(false);// to Expand the SearchView when clicked
return true;
}
return false;
}
And at search item in menu.xml make
showAsAction="always"
Note: I am using android.support.v7.widget.SearchView but in your case it doesn't matter
Related videos on Youtube
Rafal Gałka
Updated on July 11, 2020Comments
-
Rafal Gałka almost 4 years
How to build
ActionBar
with collapsible search view with single action item visible, when search view is expanded? To be more descriptive, this is what I need:Note that there are other menu items and
android:uiOptions="splitActionBarWhenNarrow"
is defined inAndroidManifest.xml
.I tried to set up custom search item layout:
menu.xml
<item android:id="@+id/menu_search" android:actionLayout="@layout/actionbar_search" android:icon="@drawable/action_search" android:showAsAction="always|collapseActionView" android:title="@string/search" />
actionbar_search.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="right" android:orientation="horizontal" > <com.actionbarsherlock.widget.SearchView android:id="@+id/search_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:iconifiedByDefault="false" android:queryHint="@string/search_hint" /> <ImageButton android:id="@+id/add_item" android:layout_width="wrap_content" android:layout_height="match_parent" style="@style/Widget.Sherlock.ActionButton" android:src="@drawable/content_new"/> </LinearLayout>
But by default search view takes all available width and button is not visible. I don't know how to force
SearchView
to fill all available space between app icon and menu item. All I found isandroid:maxWidth
property, but this only allows to hardcoded dimension, and I'm looking for some more flexible solution. I tried alsoRelativeLayout
withandroid:layout_toRightOf="@id/search_view"
with no luck. -
Rafal Gałka about 11 yearsTried this approach. As I mentioned there are other menu items and all of them overflows to bottom actionbar. And I need this one add action always placed in right top corner.
-
JPMagalhaes about 11 yearsThe detail in this case is the split action bar, not the collapsable search view. Check the link bellow. It is not possible to set this behavior using native objects. You'll need to create your own customized action bar. stackoverflow.com/questions/8571754/…
-
Rafal Gałka about 11 yearsThanks for advice, but I already tried this one too. Custom ActionBar gives me custom view when SearchView is collapsed. Then I have my single button at the top bar and those form menu.xml at the bottom. The problem is when SearchView is expanded. I need to force it to fill all available space between app icon and single action item. I tried understand what is happening in
onMeasure()
of SearchView class but not exactly understand what I can do with this, and if it is, at all, a right direction. Any help would be appreciated. -
JPMagalhaes about 11 yearsHave you tried to create your own action view class? May be you can simply extend SearchView class but I'm not sure. In resume, what you can do is: 1. Create a class that implements CollapsibleActionView (may be extending SearchView); Where you can implement onActionViewExpanded() adding a button for your menu item after the TextEdit. 2. set this class as the action view class on your menu item: android:actionViewClass="your.package.YourSearchView"
-
AndoAiron about 11 yearsHi, I have tried your above solution but it is not working at all. In fact I am not able to see any of the action item.
-
Rafal Gałka about 11 yearsCan you post fragments of your code (eg. as gist)? I spent few days figuring it out and testing, think I can help.
-
AndoAiron about 11 yearswhere should I post my code fragment ?? I can't post my problem code here as a comment. Also, could you please help me to achieve this : stackoverflow.com/questions/15947557/…
-
Rafal Gałka about 11 yearsYou can use, for example gist.github.com for posting code fragments and paste link here. If I find some time today I will try to help in your question.
-
AndroidGecko almost 11 yearsJust so you know that its much easier to achieve this by using RelativeLayout inside actionbar_search.xml and simply give imageButton alignParentRight=true. Also you need to add android:layout_toLeftOf="@+id/add_item" to your SearchView. Just tested, works just fine
-
Ajay Pandya over 8 years@salma yes you right android.support.v7.widget.SearchView and android.widget.searchview its matter a lot