Android - 操作栏中的SearchView上的NullPointerException

时间:2013-09-16 16:25:53

标签: android nullpointerexception android-actionbar searchview

我在我的活动中尝试将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>

8 个答案:

答案 0 :(得分:106)

尝试用以下代码替换失败的行:

mSearchMenuItem = menu.findItem(R.id.action_search);
mSearchView = (EnglishVerbSearchView) MenuItemCompat.getActionView(mSearchMenuItem);

其中R.id.action_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>

答案 1 :(得分:25)

我有一个类似的可能出现在我的发布版本上但不是我的调试版本切换到v21支持库时。原来是一个混淆问题,并将此行添加到我的proguard-rules.txt文件修复它:

-keep class android.support.v7.widget.SearchView { *; }

答案 2 :(得分:25)

首先检查您使用 appViewClass app 命名空间。

android:actionViewClass="android.support.v7.widget.SearchView" - 这会引发NPE

app:actionViewClass="android.support.v7.widget.SearchView" - 使用此

和第二

检查您是否在searchView以及活动

中使用相同 menu.xml

答案 3 :(得分:1)

我有一个非常类似的问题,其中以下行返回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">

答案 4 :(得分:0)

我认为你占据 FragmentActivity ,你需要扩展 ActionBarActivity

答案 5 :(得分:0)

对于任何仍在搜索的人,我都遵循了上述所有内容,似乎无法继续前进。我把我的searchView.setSearchableInfo ...包裹在一个空检查中,瞧!它就像它应该的那样运行。

if (searchView != null) {
    searchView.setSearchableInfo(searchManager.getSearchableInfo(
                    new ComponentName(getApplicationContext(), SearchActivity.class)));
}

答案 6 :(得分:0)

对我来说,这是正确的答案: 在menu / options_menu.xml中,使用:

Array
(
    [mihpayid] => 40399371551*******  
    [mode] => DC  
    [status] => success  
    [unmappedstatus] => captured  
    [key] => d****A  
    [txnid] => INV0****0531  
    [amount] => 1000.0  
    [addedon] => 2017-05-31 13:16:12  
    [productinfo] => ****  
    [firstname] => ****  
    [lastname] =>   
    [address1] =>   
    [address2] =>   
    [city] => null  
    [state] =>   
    [country] => null  
    [zipcode] =>       
    [email] => ***@test.xxx  
    [phone] =>   
    [udf1] =>   
    [udf2] =>   
    [udf3] =>   
    [udf4] =>   
    [udf5] =>   
    [udf6] =>   
    [udf7] =>   
    [udf8] =>   
    [udf9] =>   
    [udf10] =>   
    [hash] => ***************  
    [field1] => 715140****61  
    [field2] => 99***9  
    [field3] => 8523310*****511  
    [field4] => -1  
    [field5] =>   
    [field6] =>   
    [field7] =>   
    [field8] =>   
    [field9] => SUCCESS  
    [PG_TYPE] => HDFCPG  
    [encryptedPaymentId] => DB****EB8****02A****9FE4C****CB3  
    [bank_ref_num] => 8****016137****  
    [bankcode] => MAST  
    [error] => E000  
    [error_Message] => No Error  
    [name_on_card] => payu  
    [cardnum] => 512345XXXXXXXX46  
    [cardhash] => This field is no longer supported in postback params.  
    [amount_split] => {"PAYU":"1000.0"}  
    [payuMoneyId] => 1******0  
    [discount] => 0.00  
    [net_amount_debit] => 1000  
)  

答案 7 :(得分:-2)

我遇到了同样的问题。我的解决方案是: 更换 android:actionViewClass="android.support.v7.widget.SearchView"

android:actionViewClass="android.widget.SearchView"