Android – 在Actionbar中的SearchView的NullPointerException
我有一个问题试图添加一个SearchView小部件到我的活动中的ActionBar – 我调用getActionView获取我的SearchView对象时,我得到一个空值。
我一直在关注Android开发者指南,并且经历了大量的SO问题以及互联网上的其他一些链接; 一切都无济于事。 这可能是简单的,但我无法弄清楚 – 在我看来,我的代码基本上是从谷歌相同(除了改变一些名字等),但它仍然不会工作。
任何帮助,将不胜感激。
下面包含的是代码的相关位。 请让我知道是否有什么不清楚,如果你有什么可能是错误的想法。
活动代码:
private ListView workflowListView; private DrawerLayout drawerLayout; private ListView drawerList; private ActionBarDrawerToggle drawerToggle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_ACTION_BAR); setContentView(R.layout.activity_workflow_list); workflowListView = (ListView) findViewById(R.id.workflowListView); drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); drawerList = (ListView) findViewById(R.id.drawer_list); drawerToggle = new ActionBarDrawerToggle( this, /* host Activity */ drawerLayout, /* DrawerLayout object */ R.drawable.ic_launcher, /* nav drawer icon to replace 'Up' caret */ R.string.app_name, /* "open drawer" description */ R.string.app_name /* "close drawer" description */ ) { /** Called when a drawer has settled in a completely closed state. */ public void onDrawerClosed(View view) { // getActionBar().setTitle("Closed drawer"); } /** Called when a drawer has settled in a completely open state. */ public void onDrawerOpened(View drawerView) { // getActionBar().setTitle("Open drawer"); } }; drawerLayout.setDrawerListener(drawerToggle); ActionBar actionBar = getActionBar(); actionBar.setDisplayShowTitleEnabled(false); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true); actionBar.setIcon(android.R.color.transparent); String[] testData = {"a", "b", "c", "d"}; ArrayList<String> workflowList = new ArrayList<String>(); for (String s : testData) { workflowList.add(s); } ArrayAdapter<String> workflowAdapter = new ArrayAdapter<String>(this.getApplicationContext(), R.layout.workflow_list_item, workflowList); workflowListView.setAdapter(workflowAdapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.workflow_list, menu); inflater.inflate(R.menu.options_menu, menu); // Associate searchable configuration with the SearchView SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); // The below line returned null even though it was used in Google sample code SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); return super.onCreateOptionsMenu(menu); }
XML / searchable.xml:
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:hint="@string/search_hint" android:includeInGlobalSearch="false" />
菜单/ options_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/search" android:title="@string/search_title" android:icon="@drawable/ic_action_search" android:showAsAction="always|collapseActionView" android:actionViewClass="android.support.v7.widget.SearchView" /> </menu>
尝试用以下代替失败的行:
mSearchMenuItem = menu.findItem(R.id.action_search); mSearchView = (EnglishVerbSearchView) MenuItemCompat.getActionView(mSearchMenuItem);
其中R.id.action_search是菜单中search项的ID。
编辑
你的清单应该是这样的:
<activity android:name="com.bronzelabs.twc.activities.WorkflowListActivity" android:label="@string/app_name" android:theme="@style/Theme.AppCompat.Light" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".activities.SearchResultActivity" android:theme="@style/Theme.AppCompat.Light" android:launchMode="singleTop"> <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" android:value=".activities.SearchResultActivity" /> </activity>
你调用setSearchableInfo
的方式是:
mSearchView.setSearchableInfo(searchManager.getSearchableInfo( new ComponentName(getApplicationContext(), SearchResultActivity.class)));
编辑2
确保你的菜单xml文件是这样的(注意这两个属性与yourapp
命名空间 – 当你使用compat库时需要):
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:yourapp="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/action_search" android:title="@string/action_search" android:icon="@drawable/action_search" yourapp:showAsAction="always|collapseActionView" yourapp:actionViewClass="android.support.v7.widget.SearchView" /> </menu>
我有一个类似的可能出现在我的发布版本,但不是我的debugging版本切换到v21支持库时。 原来是一个混淆的问题,并将此行添加到我的proguard-rules.txt文件中修复它:
-keep class android.support.v7.widget.SearchView { *; }
首先检查你正在使用appView命名空间来处理actionViewClass 。
android:actionViewClass="android.support.v7.widget.SearchView"
– 这将引发NPE
app:actionViewClass="android.support.v7.widget.SearchView"
-use this
第二
检查你是否在menu.xml
和你的Activity中使用相同的 searchView
我有一个非常类似的问题,其中以下行返回null
SearchView searchView = (android.support.v7.widget.SearchView)MenuItemCompat.getActionView(searchMenuItem);
修正是在我的styles.xml
文件,我改变了我的AppTheme的父母Theme.AppCompat.Light
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light">
我认为你占用了FragmentActivity ,你需要扩展 ActionBarActivity
对于仍在search的人来说,我遵循上面的一切,似乎无法完成任何事情。 我包裹了我的searchView.setSearchableInfo …在一个空检查,瞧! 它就像它应该运行。
if (searchView != null) { searchView.setSearchableInfo(searchManager.getSearchableInfo( new ComponentName(getApplicationContext(), SearchActivity.class))); }
对我来说,这是正确的答案:在menu / options_menu.xml中,使用这个:
app:actionViewClass="android.support.v7.widget.SearchView"
我有同样的问题。 我的解决scheme是:replaceandroid:actionViewClass="android.support.v7.widget.SearchView"
android:actionViewClass="android.widget.SearchView"