#android #android-actionbar #searchview
#Android #android-панель действий #searchview
Вопрос:
Я хочу иметь вид поиска и две кнопки на панели действий. Итак, я создал menu/options_menu.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@ id/action_search"
android:title="Search"
android:icon="@drawable/ic_menu_search"
android:showAsAction="always"
android:actionViewClass="android.widget.SearchView" />
<item
android:title="Route"
android:id="@ id/action_route"
android:icon="@drawable/route"
android:showAsAction="always" />
<item
android:title="Cancel"
android:id="@ id/action_cancel"
android:icon="@drawable/cancel"
android:showAsAction="always" />
</menu>
Я раздуваю его в коде:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
return true;
}
Это то, что я получаю:
Как вы можете видеть, отображается только первый элемент («маршрут»). Я могу сделать видимым второй элемент («отмена»), если я разрешу значок виджета поиска:
//searchView.setIconifiedByDefault(false);
Тем не менее, я хочу, чтобы виджет поиска был расширен и оба элемента были видны. Возможно ли это?
Обновить
Мне удалось сделать их видимыми, установив android:orderInCategory="1"
для «Маршрут» и «Отмена» и android:orderInCategory="2"
для виджета поиска:
Это почти то, что я хотел. Проблема в том, что я хочу, чтобы виджет поиска был первым (крайним слева), а затем эти два элемента. Возможно ли это?
Обновление 2
Я попробовал «рекомендуемый» способ. Я установил для SearchView
:
android:showAsAction="always|collapseActionView"
После того, как я нажимаю на значок поиска, я получаю расширенный вид:
Две проблемы:
- (Незначительный) Пользовательский интерфейс навигации занимает комнату слева, что уменьшает доступное пространство для
SearchView
. - (Основной) Значок Android отображается как часть пользовательского интерфейса навигации. Могу ли я избавиться от него?
Комментарии:
1. Поймите это. Пользователь нажмет кнопку поиска и захочет взаимодействовать с расширенным виджетом поиска. Остальное их не волнует. Они хотят выполнить поиск. Любая другая кнопка просто отвлекает. Любые кнопки, которые не связаны с текущей задачей, могут быть скрыты. Это псевдопроблема. Сверните кнопку поиска по умолчанию, как показано здесь developer.android.com/training/search/setup.html .
2. @Eugen Pechanec Спасибо за ваш комментарий. Я попробовал то, что вы предлагаете, и обновил свой вопрос. Могу ли я удалить значок Android, который отображается в левой части панели действий?
3. Если вы используете тему Material или AppCompat (настоятельно рекомендуется), стрелка навигации закрывает вид поиска, а значок исчезает. Если вы не можете использовать темы Material или AppCompat, позвоните
getActionBar().setIcon(new ColorDrawable(0));
, чтобы удалить значок.4. @Nick мой ответ работает или нет?
5. @Nick мой ответ полезен?
Ответ №1:
Создал одну демонстрацию, проверьте ее :
menu.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:title="Search"
android:icon="@android:drawable/ic_search_category_default"
app:actionLayout="@layout/searchview"
app:showAsAction="always|collapseActionView"/>
<item
android:title="Route"
android:id="@ id/action_route"
android:icon="@mipmap/ic_launcher"
app:showAsAction="always" />
<item
android:title="Cancel"
android:id="@ id/action_cancel"
android:icon="@mipmap/ic_launcher"
app:showAsAction="always" />
</menu>
searchview.xml :
<?xml version="1.0" encoding="utf-8"?>
<SearchView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Java :
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
if(searchItem!=null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
}
return true;
}
Отредактированная Java на основе требований (всегда открывайте searchview) :
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
MenuItem searchItem = menu.findItem(R.id.action_search);
searchItem.expandActionView();
final SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
if(searchItem!=null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
// This listener use for handle back press if you want to go back without collapsing searchview
MenuItemCompat.setOnActionExpandListener(searchItem,new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
onBackPressed();
return false;
}
});
}
return true;
}
Скриншоты :
Комментарии:
1.
MenuItemCompat.setOnActionExpandListener
не рекомендуется. Есть ли какой-либо код для его замены?
Ответ №2:
Я сделал это, установив максимальную ширину для вида поиска, равную ширине экрана, минус ширина элемента действия.
res/menu/search.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/action_search"
android:icon="@drawable/ic_search_white_24dp"
android:title="@string/title_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always" />
<item
android:id="@ id/action_filter"
android:icon="@drawable/ic_filter_list_white_24dp"
android:title="@string/title_filter"
app:showAsAction="always" />
</menu>
Действие или фрагмент:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search, menu);
searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setIconified(false);
searchView.setMaxWidth(getSearchViewMaxWidth());
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
performSearch("");
return true; // Disable dismissing the search view
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
performSearch(query);
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
}
@Px
private int getSearchViewMaxWidth() {
final int screenWidth = getResources().getDisplayMetrics().widthPixels;
final int actionItemWidth = getResources().getDimensionPixelSize(R.dimen.action_item_width);
return screenWidth - actionItemWidth;
}
res/values/dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- ... -->
<dimen name="action_item_width">48dp</dimen>
</resources>
Ответ №3:
Измените свой onCreateOptionsMenu
следующим образом, чтобы явно установить пункты меню, видимые, когда элемент SearchView
меню имеет фокус.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
if (menu.getItem(0).isFocused()) //detect if search view has focus
{
//explicitly set menu items visible
menu.getItem(1).setVisible(true);
menu.getItem(2).setVisible(true);
}
return true;
}
Комментарии:
1. у меня это не работает. второй элемент (отмена) по-прежнему не отображается в портретном режиме.
Ответ №4:
вы можете настроить ширину расширенного представления поиска следующим образом
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
ActionBar.LayoutParams params = new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.MATCH_PARENT);
params.width=500;
searchView.setLayoutParams(params);
menu.findItem(R.id.action_search).expandActionView();
return true;
}
Ответ №5:
попробуйте это:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@ id/action_search"
android:title="Search"
android:icon="@drawable/ic_menu_search"
android:orderInCategory="1"
android:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="android.widget.SearchView" />
<item
android:title="Route"
android:id="@ id/action_route"
android:icon="@drawable/route"
android:orderInCategory="2"
android:showAsAction="always" />
<item
android:title="Cancel"
android:id="@ id/action_cancel"
android:icon="@drawable/cancel"
android:orderInCategory="2"
android:showAsAction="always" />
</menu>