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