web-dev-qa-db-ja.com

Android-アクションバーのSearchViewでのNullPointerException

SearchViewウィジェットをアクティビティのActionBarに追加しようとして問題が発生しました。getActionViewを呼び出してSearchViewオブジェクトを取得すると、null値が取得されます。

私は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" />

menu/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>
46
JakeP

失敗した行を次のものに置き換えてみてください。

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

ここで、R.id.action_searchはメニュー内の検索項目のIDです。

[〜#〜] edit [〜#〜]

マニフェストは次のようになります。

<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名前空間を持つこれら2つの属性に注意してください-これは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>
106
Szymon

まず、actionViewClassapp名前空間を使用していることを確認します。

Android:actionViewClass="Android.support.v7.widget.SearchView"-これはNPEをスローします

app:actionViewClass="Android.support.v7.widget.SearchView"-これを使用

そして第二

menu.xmlおよびActivitysamesearchViewを使用しているかどうかを確認します。

25
ketankk

V21サポートライブラリに切り替えると、おそらくデバッグビルドではなく、リリースビルドに表示される類似したものがありました。難読化の問題であることが判明し、この行をproguard-rules.txtファイルに追加すると修正されました。

-keep class Android.support.v7.widget.SearchView { *; }
25
waynesford

次の行が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">
1
Parampal Pooni

私にとって、これは正しい答えです:menu/options_menu.xmlで、これを使用してください:

app:actionViewClass="Android.support.v7.widget.SearchView"
0
liang

まだ検索している人のために、私は上記のすべてに従いましたが、物事を進めることができなかったようです。 searchView.setSearchableInfo ...をnullチェックと出来上がりでラップしました!本来あるべきように走りました。

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

FragmentActivityを占有していると思います。extend of ActionBarActivity

0
steving21