web-dev-qa-db-ja.com

動作するアクションバーで検索ビューを取得できません

私はJavaおよびAndroid開発;に初めて、そしてSearchViewのアクションバーが必要なアプリに取り組んでいます。 Googleの例を見てきましたが、うまくいかないので、何か間違ったことをしているので、アプリ開発をあきらめようとしています:私を助けることができます:)

問題:必要に応じて検索ビューを開くことができますが、その後何も起こらず、自分のsearchManager.getSearchableInfo(getComponentName())はnullを返します。また、指定したというヒントが検索ボックスに表示されないため、アプリがsearchable.xmlを見つけられない可能性があります。十分な話:)

MainActivity.Java

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);

        // Get the SearchView and set the searchable configuration
        SearchManager searchManager =
            (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView =
            (SearchView) menu.findItem(R.id.menu_search).getActionView();
        searchView.setSearchableInfo(
            searchManager.getSearchableInfo(getComponentName()));

        return true;
    }
}

searchable.xml

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:hint="@string/search_hint"
    Android:label="@string/app_label">
</searchable>

Androidmanifest

<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
    package="com.example.searchapp"
    Android:versionCode="1"
    Android:versionName="1.0" >

    <uses-sdk
        Android:minSdkVersion="14"
        Android:targetSdkVersion="15" />

    <application
        Android:icon="@drawable/ic_launcher"
        Android:label="@string/app_name"
        Android:theme="@style/AppTheme" >

        <activity Android:name=".SearchableActivity" >
            <intent-filter>
                <action Android:name="Android.intent.action.SEARCH" />
            </intent-filter>
        </activity>

        <activity
            Android:name=".MainActivity"
            Android:label="@string/title_activity_main" >
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />
                <category Android:name="Android.intent.category.LAUNCHER" />
            </intent-filter>           
        </activity>

        <meta-data Android:name="Android.app.searchable"
                   Android:resource="@xml/searchable"/>          

    </application>

</manifest>

SearchableActivity.Java

package com.example.searchapp;

import Android.app.ListActivity;
import Android.app.SearchManager;
import Android.content.Intent;
import Android.os.Bundle;
import Android.util.Log;

public class SearchableActivity extends ListActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search);

        // Get the intent, verify the action and get the query
        Intent intent = getIntent();
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
          String query = intent.getStringExtra(SearchManager.QUERY);
          doMySearch(query);
        }
    }

    private void doMySearch(String query) {
        Log.d("Event",query);
    }
}

そして、ここに紹介されたプロジェクトへのリンクがあります、誰かがこれで私を助けてくれたら永遠に感謝します!

ソースコード

66

問題はAndroidManifestにあります。それはドキュメントに従っているので、私はあなたと同じように持っていました。しかし、それは不明瞭または間違っています。

APIデモのソースを見ると、「Android.app.searchable」メタデータが「results」アクティビティに含まれている必要があり、メインアクティビティ(またはSearchViewを配置するアクティビティ)で「 Android.app.default_searchable」。

私のテストプロジェクトからのマニフェストである次のファイルでそれを見ることができます:

<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.example.test"
Android:versionCode="1"
Android:versionName="1.0" >

<uses-sdk
    Android:minSdkVersion="8"
    Android:targetSdkVersion="15" />

<application
    Android:icon="@drawable/ic_launcher"
    Android:label="@string/app_name"
    Android:theme="@style/AppTheme" >
    <activity
        Android:name=".MainActivity"
        Android:label="@string/title_activity_main" >
        <intent-filter>
            <action Android:name="Android.intent.action.MAIN" />

            <category Android:name="Android.intent.category.LAUNCHER" />
        </intent-filter>

        <meta-data
            Android:name="Android.app.default_searchable"
            Android:value=".SearchActivity" />
    </activity>
    <activity
        Android:name=".SearchActivity"
        Android:label="@string/app_name" >

        <!-- This intent-filter identifies this activity as "searchable" -->

        <intent-filter>
            <action Android:name="Android.intent.action.SEARCH" />

            <category Android:name="Android.intent.category.DEFAULT" />
        </intent-filter>

        <!-- This metadata entry provides further configuration details for searches -->
        <!-- that are handled by this activity. -->

        <meta-data
            Android:name="Android.app.searchable"
            Android:resource="@xml/searchable" />
    </activity>
</application>

Searchable.xmlのヒントとラベルが参照であり、ハードコーディングされた文字列ではないことも重要です。

それがあなたの問題を解決することを願っています。それを理解するのに一日中かかった:(

147
Sloy

Androidガイドは次のように明示しています:

// Assumes current activity is the searchable activity
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

あなたの場合、これは真実ではありません。 MainActivityではなくSearchableActivityで検索するためです。つまり、getComponentName()メソッドの代わりにこのComponentNameを使用する必要があります。

ComponentName cn = new ComponentName(this, SearchableActivity.class);
searchView.setSearchableInfo(searchManager.getSearchableInfo(cn));
82
bakua

また、Android:hint属性とAndroid:label属性の両方[〜#〜] must [〜#〜]は、strings.xmlの文字列への参照であるようです。文字列値を遅延させてハードコーディングすると、まったく機能しないようです:)

つまり、しないでください:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:hint="Search for something..."
    Android:label="My App">
</searchable>

しかし、間違いなく(OPが正しくしたように):

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:hint="@string/search_hint"
    Android:label="@string/app_label">
</searchable>
13
NPike

Android Studioを使用している場合、

<meta-data
            Android:name="Android.app.default_searchable"
            Android:value=".SearchActivity" />

一部が機能しない場合があります。

のような完全なパッケージ名を書く

<meta-data
                Android:name="Android.app.default_searchable"
                Android:value="com.example.test.SearchActivity" />
7
togikan

「xml/searchable.xml」に注意してください。 Android:hintおよびAndroid:labelでハードコードを作成した場合、機能しません。ハハは:

<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:hint="@string/app_name"
Android:label="@string/search_lb"
Android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"/>
6

searchables.xmlファイルが正しい場所にあります(つまり、res/xml/フォルダー)および同じファイルにエラーが含まれていない-そうでない場合は(SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName)はnullを返し、検索機能を破壊します。

(また、Androidガイドに示されている例は、同じアクティビティで検索を行って検索を表示している場合にのみ使用されるため、componentNameを適切な方法で設定してください。 )

2

上記の回答で説明したように、実際には「欠落部分」を使用する必要はありません。このメソッド(SearchViewを使用)は、公式ドキュメントが Searchウィジェットの使用 までのように機能します。ここでは、次のように少し変更する必要があります。

SearchableInfoのプロパティは、ラベル、ヒント、提案の表示、検索結果画面の起動および音声ボタンなどの他のアフォーダンスの制御のためのインテントの作成に使用されます( docs )。

したがって、SearchView.setSearchableInfo(SearchableInfo s)に渡すSearchableInfoオブジェクトには、検索結果を表示するために表示されるターゲットアクティビティへの適切な参照が含まれている必要があります。これは、ターゲットアクティビティのComponentNameを手動で渡すことで実行されます。 ComponentNameを作成するための1つのコンストラクターは

public ComponentName (String pkg, String cls)

pkgclsは、検索結果を表示するために起動されるターゲットアクティビティのパッケージ名とクラス名です。ご了承ください:

pkgはプロジェクトのルートパッケージ名を指している必要があり、

clsはクラスの完全修飾名でなければなりません(つまり、全体)

例えば。:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    // Get the SearchView and set the searchable configuration
String pkg = "com.example.musicapp"
String cls = "com.example.musicapp.search.SearchActivity"
ComponentName mycomponent = new ComponentName(pkg,cls);       
SearchManager searchManager =(SearchManager)getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(mycomponent));
searchView.setIconifiedByDefault(false);   //if using on actionbar
return true;
}

要件に応じて、他のComponentNameコンストラクターを見てください。

2
Kedar Paranjape