MenuItemCompat.getActionView всегда возвращает null

Я только что реализовал библиотеку поддержки v7 AppCompat но MenuItemCompat.getActionView всегда возвращает значение null в каждой проверенной вами версии Android (4.2.2, 2.3.4 ….)

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

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> 

Наконец я нашел решение.

  1. Изменение пространства имен actionViewClass от android:actionViewClass в app:actionViewClass

  2. Внедрение интерфейса android.support.v7.widget.SearchView.OnQueryTextListener для текущей активности.

  3. Непосредственно используйте 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.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> 

Я был с той же ошибкой, мой метод 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 .

Я думаю, что проблема в том, что вы используете SearchView из пакета поддержки V7, и, возможно, ваш уровень API установлен на ….. 22 ??.

Чтобы устранить проблему, измените код следующим образом:

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

Ответ Мохсена Афшина выше был моей отправной точкой, и я сделал некоторые хитрости, чтобы заставить его работать с моей установкой:

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

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> 

У меня был тот же код, но вместо использования import 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, и разрешить любые пользовательские настройки, которые он использует (добавьте больше по мере необходимости)»

Удалить код: public class DemoActivity расширяет ActionBarActivity

Заменить на: public class DemoActivity extends Activity