3

公式ドキュメントによると、検索インターフェイスを提供するには、検索ダイアログまたはSearchViewウィジェットのいずれかを使用する 2 つの方法があります。この 2 つの方法を使用して、検索コンテキスト データを渡すことに注意したいと思います。

したがって、ドキュメントには次のように記載されています。

..システムが検索可能なアクティビティに送信するインテントに追加のデータを提供できます。ACTION_SEARCH インテントに含まれる APP_DATA バンドルで追加データを渡すことができます。

この種のデータを検索可能なアクティビティに渡すには、ユーザーが検索を実行できるアクティビティの onSearchRequested() メソッドをオーバーライドし、追加のデータを含む Bundle を作成し、startSearch() を呼び出して検索ダイアログをアクティブにします。例えば:

@Override
public boolean onSearchRequested() {
     Bundle appData = new Bundle();
     appData.putBoolean(SearchableActivity.JARGON, true);
     startSearch(null, false, appData, false);
     return true;
}

..ユーザーがクエリを送信すると、追加したデータと共に検索可能なアクティビティに配信されます。APP_DATA バンドルから余分なデータを抽出して、検索を絞り込むことができます。例えば:

Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
if (appData != null) {
    boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
}

これは検索ダイアログを指します。検索ウィジェットはどうですか?

SearchViewウィジェットのみを使用して検索コンテキスト データを渡すことは可能ですか?

誰かが明確な説明をしたり、目標を達成するための別の方法や同様の方法を提案したりできることを願っています。

ありがとう!

4

2 に答える 2

9

私は解決策を発見しました。2つのソリューションでも!

呼び出す必要がないためonSearchRequested()、検索ダイアログはまったくありません:)

最初に、検索インターフェースを作成するための一般的な手順をいくつか示してから、ソースの問題の解決策を示します。

res/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"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity" >

    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_action_search"
        android:title="@string/search_string"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="android.support.v7.widget.SearchView" />

</menu>

ファイルに検索可能な構成を作成しres/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" />

で 2 つのアクティビティを宣言しますAndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.searchinterface">

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

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

        <activity android:name=".SearchableActivity"
            android:label="@string/app_name"
            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"/>
        </activity>

    </application>

</manifest>

ACTION_SEARCHから渡されたインテントと検索コンテキスト データを処理する Searchable Activity を作成しますMainActivity。から余分なデータを抽出APP_DATA Bundleして、検索を絞り込みます。

public class SearchableActivity extends AppCompatActivity {
    public static final String JARGON = "com.example.searchinterface.jargon";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_searchable);

        handleIntent(getIntent());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        handleIntent(intent);
    }

    private void handleIntent(Intent intent) {

        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            // use the query to search the data somehow

            Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
            if (appData != null) {
                boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
                // use the context data to refine our search
            }
        }
    }
}

MainActivity次に、クラスを実装する必要があります。そのため、メニューを拡張し、SearchView要素も構成します。SearchView.OnQueryTextListenerまた、特に を設定してそのメソッドを実装する必要がありonQueryTextSubmit()ます。ユーザーが送信ボタンを押すと呼び出され、検索コンテキスト データを に渡すメイン ロジックが含まれていますSearchableActivity。ついに、主な回答セクションに到達しました。私が言ったように、2つの解決策があります:

Bundle1.エクストラでインテントを作成し、SearchableActivity手動で送信します。

MainActivity必要なすべての内容を次に示します。

public class MainActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {
    private SearchView mSearchView;

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

        MenuItem searchItem = menu.findItem(R.id.action_search);
        mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);

        // associate searchable configuration with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        mSearchView.setSearchableInfo(searchManager.getSearchableInfo(
                new ComponentName(this, SearchableActivity.class)));

        mSearchView.setOnQueryTextListener(this);

        return true;
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        Intent searchIntent = new Intent(this, SearchableActivity.class);
        searchIntent.putExtra(SearchManager.QUERY, query);

        Bundle appData = new Bundle();
        appData.putBoolean(SearchableActivity.JARGON, true); // put extra data to Bundle
        searchIntent.putExtra(SearchManager.APP_DATA, appData); // pass the search context data
        searchIntent.setAction(Intent.ACTION_SEARCH);

        startActivity(searchIntent);

        return true; // we start the search activity manually
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        return false;
    }
}

https://stackoverflow.com/a/22184137/6411150に感謝します。

2 番目の解決策も追加されてonQueryTextSubmit()います (必須ではありません)。

2. 検索コンテキスト データを作成し、 のメソッドにBundle渡します。setAppSearchData()SearchView

そのため、検索インテント全体を作成して渡し、それぞれの検索可能なアクティビティを起動する必要はありません。システムが処理します。

別のコード スニペットを次に示します。

/*
 You may need to suppress the “restrictedApi” error that you could possibly
 receive from this method "setAppSearchData(appData)”.I had to
 I’m targetSdkVersion 26. I’m also using Android Studio 3 
 with the new gradle plugin, which might be causing this.

 If you’re not running Android Studio 3 you can simply put
 “//noinspection RestrictedApi" 
  right above the line: mSearchView.setAppSearchData(appData);
 */
@SuppressWarnings("RestrictedApi")
@Override
public boolean onQueryTextSubmit(String query) {
    Bundle appData = new Bundle();
    appData.putBoolean(SearchableActivity.JARGON, true); // put extra data to Bundle
    mSearchView.setAppSearchData(appData); // pass the search context data

    return false; // we do not need to start the search activity manually, the system does it for us 
}

https://stackoverflow.com/a/38295904/6411150に感謝します。

注:サポート ライブラリのSearchView( android.support.v7.widget.SearchView)のバージョンのみにsetAppSearchData()メソッドが含まれているため、注意してください。

于 2016-08-22T14:30:56.857 に答える