Android ActionBar: складной вид поиска с кнопкой действия


Как построить ActionBar со складным видом поиска с одним элементом действия видимым, когда вид поиска расширен? Чтобы быть более описательным, вот что мне нужно:

Введите описание изображения здесьОбратите внимание, что есть и другие пункты меню и android:uiOptions="splitActionBarWhenNarrow" определяется в AndroidManifest.xml.

Я попытался настроить пользовательский макет элемента поиска:

Меню

.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>

Но по умолчанию вид поиска занимает всю доступную ширину, а кнопка нет видимый. Я не знаю, как заставить SearchView заполнить все доступное пространство между значком приложения и пунктом меню. Все, что я нашел, - это свойство android:maxWidth, но это позволяет только жестко закодировать размерность, и я ищу какое-то более гибкое решение. Я пытался также RelativeLayout с android:layout_toRightOf="@id/search_view", но безуспешно.

4 20

4 ответа:

После рассмотрения предложений из комментариев, многие гугля и тестирования преуспели в получении желаемого эффекта. Я не горжусь этим решением, но оно работает, оно не слишком сложное и должно быть достаточным для этого случая.

В резюме, что я сделал:

  1. помещается SearchView с пользовательской кнопкой "добавить элемент" в customView из ActionBar.
  2. удалены collapseActionView и android:actionLayout из элемента поиска в menu.xml
  3. сворачивание/расширение SearchView программно.

Некоторые код, чтобы лучше понять, что я сделал. Может быть, это кому-то и пригодится.

Меню

.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>

Основная активность.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;
    }

    // ...
}

Вы можете сделать это только с помощью yourmenu.XML.

Установите другой значок меню, чтобы он всегда отображался как действие. Ваше меню.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"
/>
<item
    android:id="@+id/your_other_menu_id"
    android:showAsAction="always"
    android:icon="@android:drawable/your_other_menu_ic"
 />

Просто вы можете сделать это так

@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;
}

И при поиске пункта в меню.xml make

ShowAsAction= "всегда"

Примечание: я использую android.поддержка.v7.штучка.SearchView, но в вашем случае это не имеет значения

Просто изменение меню xml. префикс showaction на свое имя

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" >

<item
    android:id="@+id/menu_search"
    android:actionLayout="@layout/actionbar_search"
    android:icon="@drawable/action_search"
    app:showAsAction="always|collapseActionView"
    android:title="@string/search"
/>

</menu>