【问题标题】:Is it possible to pass search context data using the Search Widget (SearchView) only?是否可以仅使用搜索小部件 (SearchView) 传递搜索上下文数据?
【发布时间】:2016-08-22 00:41:34
【问题描述】:

根据official documentation,提供搜索界面的方法有两种:使用搜索对话框或SearchView 小部件。我想注意使用这两种方式传递搜索上下文数据

所以,documentation 说:

..您可以在系统发送到的意图中提供其他数据 您的可搜索活动。您可以在 APP_DATA Bundle,包含在 ACTION_SEARCH 意图中。

要将此类数据传递给您的可搜索活动,请覆盖 活动的 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 的数据以优化搜索。例如:

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

这是指搜索对话框。那么搜索小部件呢?

是否可以仅使用 SearchView 小部件传递搜索上下文数据?

希望有人可以给出明确的解释和/或建议另一种或类似的方式来实现目标。

谢谢!

【问题讨论】:

    标签: android android-intent searchview android-searchmanager search-dialog


    【解决方案1】:

    我已经找到了解决方案。甚至两个解决方案!

    他们不需要调用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" />
    

    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>
    

    创建一个 Searchable Activity,我们在其中处理 ACTION_SEARCH 意图和从 MainActivity 传递的搜索上下文数据。我们从APP_DATABundle 中提取额外的数据来优化搜索:

    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 的主要逻辑。 最后,我们到达了主要答案部分。正如我所说,有两种解决方案:

    1.使用额外的Bundle 创建一个意图并将其手动发送到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

    第二个解决方案也放入onQueryTextSubmit()(但不是必须的):

    2。创建搜索上下文数据Bundle 并将其传递给SearchViewsetAppSearchData() 方法。

    因此,我们不需要创建和传递整个搜索意图并启动相应的可搜索活动,系统会处理它。

    这是另一个代码sn-p:

    /*
     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

    注意:只支持库版本的SearchViewandroid.support.v7.widget.SearchView)包含setAppSearchData()方法,请注意。

    【讨论】:

    • 我想补充一点,解决方案 2 也适用于搜索建议。建议一个也可以,但我没有使用那个。好帖子!谢谢!
    【解决方案2】:

    如果设计符合您的需求,您可以单独使用 SearchView,并为其添加一个 OnQueryTextListener,并在那里进行处理。不需要任何其他东西,不需要意图、元标记或 XML 文件。我已经这样做了几次,文档对此有点不清楚。

    【讨论】:

    • 实际上,我需要将带有SearchView 元素的活动中的搜索额外数据传递给一些可搜索的活动。我认为无论如何都应该使用意图。但是您对使用 OnQueryTextListener 是正确的。它有利于跟踪用户提交的查询。而且我也同意你的观点,文档有点不清楚:)
    猜你喜欢
    • 2012-10-20
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    相关资源
    最近更新 更多