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了解决办法。
- 
将 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> 
我认为问题是你使用支持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); 
 这对我的活动“扩展”的FragmentActivity和ActionBarActivity非常好。 
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