26

アプリケーションに Search-ActionView を追加しようとしています (ここで説明されているようにhttp://developer.android.com/guide/topics/search/search-dialog.html#UsingSearchWidget )。残念ながら、NullPointerException が発生し続け、実際に何が問題なのかを検出するのに苦労しています。

Androidページに示されているように、検索可能な構成と検索可能なアクティビティを作成しました。私のメニュー .xml ファイルは次のようになります。

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    ...
    <item
        android:id="@+id/menu_item_search"
        android:actionViewClass="android.widget.SearchView"
        android:icon="@drawable/icon_search"
        android:showAsAction="always"
        android:title="@string/action_bar_button_search">
    </item>

</menu>

これは、例外がスローされるメソッドです。

public boolean onCreateOptionsMenu( Menu menu )
{
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate( R.menu.action_bar, menu );

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.menu_item_search).getActionView();

    // NullPointerException thrown here; searchView is null.
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false);

    return super.onCreateOptionsMenu( menu );
}

完全なスタック トレース:

FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.activities.Test.onCreateOptionsMenu(Test.java:41)
at android.app.Activity.onCreatePanelMenu(Activity.java:2444)
at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:408)
at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:759)
at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:2997)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4507)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
4

7 に答える 7

49

この質問は頻繁に検索され、同じ問題に何度も出くわしたため、SearchWidget を作成するために必要なすべての手順を追跡する簡単なフォローアップを次に示します。

ただし、SearchWidget には注意が必要な部分が 1 つあります。リソースの代わりに searchable.xml でハードコーディングされた文字列を使用すると、アプリがクラッシュし、わかりにくいエラー メッセージが表示されます。これは私の人生の何時間もかかりました...

  1. 検索結果を処理するアクティビティを作成する

    public class Search extends Activity {}
    
  2. ファイル「searchable.xml」を res/xml ディレクトリに追加します (ヒントとラベルにはリソースを使用してください! )

    <searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:hint="@string/search_hint"
        android:includeInGlobalSearch="false"
        android:label="@string/search_label"
        android:searchSettingsDescription="@string/search_global_description" />
    
  3. res/menu ディレクトリに適切なメニュー項目「main.xml」を作成します。

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <item
           android:id="@+id/options_menu_main_search"
           android:actionViewClass="android.widget.SearchView"
           android:icon="@drawable/icon_magnifier"
           android:showAsAction="always"
           android:title="Search"/>
    
    </menu>
    
  4. Manifest.xml を更新します。検索アクティビティを追加し、検索インテントを受け取るアクティビティを指定します。ノードに追加<meta-data android:name="android.app.default_searchable" android:value=".app.Search" />すると、activity検索可能になります。これをノードに追加すると、applicationすべてのアクティビティが検索可能になります。

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
        <application>
            <meta-data
                android:name="android.app.default_searchable"
                android:value=".app.Search" />
    
            <activity android:name=".activities.Search" >
                <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>
    
            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>
    </application>
    

  5. SearchWidget を提供する必要があるすべてのアクティビティで、ActionView に SearchManager を追加します。

    public class Activity extends android.app.Activity
    {
        @Override
        public boolean onCreateOptionsMenu( Menu menu )
        {
            getMenuInflater().inflate( R.menu.main, menu );
    
            // Add SearchWidget.
            SearchManager searchManager = (SearchManager) getSystemService( Context.SEARCH_SERVICE );
            SearchView searchView = (SearchView) menu.findItem( R.id.options_menu_main_search ).getActionView();
    
            searchView.setSearchableInfo( searchManager.getSearchableInfo( getComponentName() ) );
    
            return super.onCreateOptionsMenu( menu );
        }
    }
    
于 2013-01-29T21:36:30.580 に答える
24

Android 2.xをターゲットにしてandroid.support.v7.widget.SearchViewを使用している場合 は、menu.xml が次のようになっていることを確認してください ( yourapp名前空間に注意してください) 。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:yourapp="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/search"
        android:title="@string/search"
        android:icon="@drawable/ic_search"
        yourapp:showAsAction="always"
        yourapp:actionViewClass="android.support.v7.widget.SearchView" />
</menu>

メニューを膨らませるアクティビティでは、次を使用します。

android.support.v7.widget.SearchView searchView = (android.support.v7.widget.SearchView) 
MenuItemCompat.getActionView(menu.findItem(R.id.search));
于 2014-03-13T16:39:55.683 に答える
20

リンクのようにこの方法を使用する

public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.action_bar, menu);
        MenuItem searchItem = menu.findItem(R.id.menu_item_search);
        SearchView searchView = (SearchView) searchItem.getActionView();


        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        if(null!=searchManager ) {   
         searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        }
        searchView.setIconifiedByDefault(false);

        return true;
    }
于 2012-06-30T17:47:46.767 に答える
8

null を返す SearchView getActionView

リンクのように、メニューxmlファイルを開いて変更します

android:actionViewClass="android.widget.SearchView"

の中へ

app:actionViewClass="android.widget.SearchView" 

これは私のために働いた

于 2016-07-21T06:12:16.017 に答える
2

私も同じ問題を抱えています。私の場合、問題を解決するように変更android:actionViewClassapp:actionViewClassます(タグxmlns:app="http://schemas.android.com/apk/res-auto"内で)。<menu>

于 2016-06-02T17:23:47.690 に答える
1

まず、SearchWidget を含む XML ファイルをレイアウト フォルダーに作成します。

<?xml version="1.0" encoding="utf-8"?>
<SearchView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/edit_query"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:inputType="textFilter"
    >

</SearchView>

次に、アクティビティで、アクション バーを取得します

android.support.v7.app.ActionBar actionBar = getSupportActionBar();

次に、検索ビューへの参照を追加します

 actionBar.setCustomView(R.layout.custom_action_bar);
    search = (EditText) actionBar.getCustomView().findViewById(
            R.id.edit_query);

次に、アクションバーの表示オプションを設定します

actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);

それでおしまい。

ところで、入力されたクエリに従って、文字列のリストを配列リストとして取得し、それらを表示する私の検索ウィジェットを使用することもできます。ユーザーが特定の結果を選択すると、選択した結果が返され、親アクティビティの onActivityResult で取得できます。

于 2016-09-03T09:45:39.797 に答える
0

この問題は、インテント フィルタの欠落によって引き起こされます。

<intent-filter>
    <action android:name="android.intent.action.SEARCH" />
</intent-filter>
于 2014-01-27T16:05:15.427 に答える