MenuItemCompat.getActionView总是返回null

我只是实现了v7 AppCompat支持库,但是MenuItemCompat.getActionView总是在我testing的每个Android版本(4.2.2,2.3.4 ….)中返回null。

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> 

最后我find了解决办法。

  1. actionViewClass命名空间从android:actionViewClassapp: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 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> 

我认为问题是你使用支持V7包中的SearchView,也许你的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> 

我有同样的错误,我的方法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"/> 

我在一些post中看到人们使用app:或者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); 

这对我的活动“扩展”的FragmentActivityActionBarActivity非常好。

Mohsen Afshin上面的答案是我的出发点,我做了一些调整,使其与我的设置工作:

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

我有相同的代码,而不是使用导入android.support.v7.widget.SearchView; 我正在使用import android.widget.SearchView; 。 这解决了我的问题与null值。 所以只要在你的search活动中改变这个代码,它就可以工作,并且改变xml文件中的命名空间。

以下是如何处理来自支持库v7的searchView代码片段:

 @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,请将其添加到其configuration中:

 -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

replace为:public class DemoActivity extends Activity