MenuItemCompat.getActionView всегда возвращает значение null
Я только что реализовал v7 AppCompat
библиотеки поддержки, но MenuItemCompat.getActionView
всегда возвращайте null в каждой версии Android, которую я тестировал (4.2.2, 2.3.4 ....)
The SearchView
отображается в панели действий, но он не реагирует на сенсорные действия и не расширяется, чтобы показать его EditText
и это так же, как простой значок.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
if (searchView != null) {
SearchViewCompat.setOnQueryTextListener(searchView, mOnQueryTextListener);
searchView.setIconifiedByDefault(false);
Log.d(TAG,"SearchView not null");
} else
Log.d(TAG, "SearchView is null");
}
return super.onCreateOptionsMenu(menu);
}
.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"
app:showAsAction="always|collapseActionView"
android:icon="@drawable/abc_ic_search"
android:title="@string/action_bar_search"
android:actionViewClass="android.support.v7.widget.SearchView"/>
<item android:id="@+id/action_refresh"
android:icon="@drawable/refresh"
android:title="@string/action_bar_refresh"
app:showAsAction="ifRoom"/>
</menu>
10 ответов:
наконец-то я нашел решение.
изменение пространства имен
actionViewClass
Сandroid:actionViewClass
доapp:actionViewClass
реализация
android.support.v7.widget.SearchView.OnQueryTextListener
интерфейс для текущей деятельности.использовать
setOnQueryTextListener
вместоSearchViewCompat.setOnQueryTextListener
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); MenuItem searchItem = menu.findItem(R.id.action_search); SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); if (searchView != null) { searchView.setOnQueryTextListener(this); } return super.onCreateOptionsMenu(menu); }
в моем случае это был файл ProGuard. Вам нужно добавить эту строку:
-keep class android.support.v7.widget.SearchView { *; }
для меня, неверный
menu.xml
импорт пространства имен вызвал эту проблему.мой изначальный
menu.xml
:<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/tools"> <item android:id="@+id/action_search" android:title="@string/map_option_search" android:icon="@drawable/ic_action_search" app:showAsAction="collapseActionView|ifRoom" app:actionViewClass="android.support.v7.widget.SearchView"/> </menu>
похоже
xmlns:app="http://schemas.android.com/tools"
вызываетMenuItemCompat.getActionView()
вернутьсяnull
. Изменение этого импорта наxmlns:app="http://schemas.android.com/apk/res-auto"
Исправлена проблема.новая работа
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="@string/map_option_search" android:icon="@drawable/ic_action_search" app:showAsAction="collapseActionView|ifRoom" app:actionViewClass="android.support.v7.widget.SearchView"/> </menu>
Я думаю, что проблема в том, что вы используете SearchView из пакета поддержки V7 и, возможно, ваш уровень API установлен на.....22??.
изменение кода на следующее, Чтобы устранить проблему:
.xml<?xml version="1.0" encoding="UTF-8" ?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_search" android:icon="@drawable/actionbar_button_search" android:title="Search" android:showAsAction="always" android:actionViewClass="android.widget.SearchView" /> </menu>
Я был с той же ошибкой, мой метод
getActionView()
всегда возвращал null. Итак, я сделал следующие вещи:<item android:id="@+id/action_search" android:icon="@drawable/abc_ic_search" android:title="@string/search_title" android:showAsAction="always" android:actionViewClass="android.widget.SearchView"/>
Я видел в некоторых сообщениях, что люди используют приложение: или yourapp, но я использовал нормально
android:ActionVewClass
.на
onCreateOptionsMenu
способ:@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.feed, menu); // Associate searchable configuration with the SearchView SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.action_search) .getActionView(); searchView.setSearchableInfo(searchManager .getSearchableInfo(getComponentName())); return true; }
и не забудьте поставить в
onCreate
способ:// enabling action bar app icon and behaving it as toggle button getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true);
это очень хорошо работает для моей деятельности "расширение" для
FragmentActivity
иActionBarActivity
.
ответ Мохсена Афшина выше был моей отправной точкой, и я сделал несколько настроек, чтобы заставить его работать с моей настройкой:
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); MenuItem searchItem = menu.findItem(R.id.action_search); // SearchView searchView = (SearchView) MenuItemCompat // .getActionView(searchItem); SearchView searchView = (SearchView) searchItem.getActionView(); if (searchView != null) { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String s) { // do something with s, the entered string query = s; Toast.makeText(getApplicationContext(), "String entered is " + s, Toast.LENGTH_SHORT).show(); return true; } @Override public boolean onQueryTextChange(String s) { return false; } }); } return super.onCreateOptionsMenu(menu); }
.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity" > <item android:id="@+id/action_search" android:orderInCategory="5" android:title="Search" android:icon="@drawable/ic_action_search" android:showAsAction="ifRoom|collapseActionView" android:actionViewClass="android.widget.SearchView" /> </menu>
у меня был тот же код, но вместо того, чтобы использовать импорт
android.support.v7.widget.SearchView;
Я был с помощьюimport android.widget.SearchView;
. Это исправило мою проблему сnull
значение. Поэтому просто измените этот код в своей поисковой активности, и он будет работать, а также изменит пространство имен в xml-файле.
вот фрагмент того, как обрабатывать searchView из библиотеки поддержки v7 :
@Override public void onCreateOptionsMenu(final Menu menu,final MenuInflater inflater) { menu.clear(); getActivity().getMenuInflater().inflate(...,menu); _searchView=(SearchView)MenuItemCompat.getActionView(_searchMenuItem); _searchView.setQueryHint(...); if(VERSION.SDK_INT<VERSION_CODES.HONEYCOMB) { final EditText searchTextView=(EditText)searchView.findViewById(R.id.search_src_text); if(searchTextView!=null) { searchTextView.setScroller(new Scroller(_context)); searchTextView.setMaxLines(1); searchTextView.setVerticalScrollBarEnabled(true); searchTextView.setMovementMethod(new ScrollingMovementMethod()); searchTextView.setTextColor(_context.getResources().getColor(App.getResIdFromAttribute(_context,android.R.attr.textColorPrimary))); } } _searchView.setOnQueryTextListener(new android.support.v7.widget.SearchView.OnQueryTextListener() { ... }); MenuItemCompat.setActionView(_searchMenuItem,_searchView); MenuItemCompat.setOnActionExpandListener(_searchMenuItem,new OnActionExpandListener() { ... }); super.onCreateOptionsMenu(menu,inflater); } public static int getResIdFromAttribute(final Activity activity,final int attr) { if(attr==0) return 0; final TypedValue typedvalueattr=new TypedValue(); activity.getTheme().resolveAttribute(attr,typedvalueattr,true); return typedvalueattr.resourceId; }
кроме того, если вы используете Proguard, добавьте это в его конфигурацию :
-keep class android.support.v4.app.** { *; } -keep interface android.support.v4.app.** { *; } -keep class android.support.v7.widget.SearchView { *; } -keepattributes *Annotation*
у меня была очень похожая проблема, с той разницей, что я пытался использовать класс, который продлен
android.widget.ImageView
Если вы используете ProGuard, вам нужно указать, чтобы разрешить методы, участвующие в этом классе.
-keep public class * extends android.widget.ImageView{ public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); public void set*(...); }
http://proguard.sourceforge.net/manual/examples.html
Это говорит: "разрешить все необходимые конструкторы, которые могут быть вызваны из xml и разрешить любые пользовательские сеттеры, которые он использует, а также (добавить больше по мере необходимости)"