Android ActionBar: collapsible SearchView with action button

35,730

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:

  1. Placed SearchView with custom "add item" button in customView of ActionBar.
  2. Removed collapseActionView and android:actionLayout from search item in menu.xml
  3. 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

Share:
35,730

Related videos on Youtube

Rafal Gałka
Author by

Rafal Gałka

Updated on July 11, 2020

Comments

  • Rafal Gałka
    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:

    enter image description here Note that there are other menu items and android:uiOptions="splitActionBarWhenNarrow" is defined in AndroidManifest.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 is android:maxWidth property, but this only allows to hardcoded dimension, and I'm looking for some more flexible solution. I tried also RelativeLayout with android:layout_toRightOf="@id/search_view" with no luck.

  • Rafal Gałka
    Rafal Gałka about 11 years
    Tried 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
    JPMagalhaes about 11 years
    The 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
    Rafal Gałka about 11 years
    Thanks 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
    JPMagalhaes about 11 years
    Have 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
    AndoAiron about 11 years
    Hi, 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
    Rafal Gałka about 11 years
    Can you post fragments of your code (eg. as gist)? I spent few days figuring it out and testing, think I can help.
  • AndoAiron
    AndoAiron about 11 years
    where 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
    Rafal Gałka about 11 years
    You 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
    AndroidGecko almost 11 years
    Just 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
    Ajay Pandya over 8 years
    @salma yes you right android.support.v7.widget.SearchView and android.widget.searchview its matter a lot