根据活动片段更改活动中的搜索功能

时间:2016-08-24 17:50:47

标签: android android-contentprovider searchview fragmentpageradapter

我有一个activityTabLayoutFragmentPagerAdapter相关联。每当用户更改选项卡时,都会加载另一个片段,但Activity保持不变。 activity还包含搜索功能,即从Web服务器获取自动完成建议。我想执行不同的搜索操作 - 基本上,查询另一个URL - 取决于FragmentPager / TabLayout中当前加载的哪个片段。 到目前为止,我还没有找到任何方法来做到这一点。以下是我的尝试:

  • 目前,搜索功能连接到内容提供商(通过manifest和searchable.xml)。但是,我还没有找到一种方法将数据传递给此ContentProvider以让它知道选择了哪个选项卡
  • 使用多个内容提供商似乎不可能,因为任何给定的活动只能有一个,并且选择另一个选项卡时活动不应该改变
  • 操纵Activity的onQueryText *方法是不可行的,因为我不想阻止获取数据的UI线程

以下是情况的快速草图:Sketch

以下是相关的代码片段:

MainActivity.class

public class MainActivity extends AppCompatActivity {
    private ViewPager mViewPager;

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

        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        mViewPager.setAdapter(new MainFragmentPagerAdapter(getSupportFragmentManager(),
                MainActivity.this));

        TabLayout tabs = (TabLayout) findViewById(R.id.sliding_tabs);
        tabs.setupWithViewPager(mViewPager);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.action_search, menu);


        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        searchView.setOnQueryTextListener(this);

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(this, MainActivity.class)));
        searchView.setIconifiedByDefault(false);

        return true;
    }

    /* ... */
}

菜单/ action_search.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/action_search"
        android:title="Search"
        android:icon="@android:drawable/ic_menu_search"
        app:showAsAction="always"
        app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>

XML / searchable.xml

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:hint="hint"
    android:label="@string/app_name"
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
    android:searchSuggestAuthority="xyz.demo.search.datasuggestion"
    android:searchSuggestIntentAction="android.intent.action.VIEW"
    android:searchSuggestIntentData="content://xyz.demo.search.data"/>

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="xyz.demo.app">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="android.app.default_searchable"
            android:value=".MainActivity" />
        <activity android:name=".MainActivity" android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.intent.action.SEARCH" />
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>

        <provider
            android:name=".SuggestionProvider"
            android:authorities="xyz.demo.search.datasuggestion"
            android:enabled="true"
            android:exported="true"/>
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

SuggestionProvider.java

public class SuggestionProvider extends ContentProvider {
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {

          OkHttpClient client = new OkHttpClient();
          Request request = new Request.Builder()
                  .url(".../suggestions")
                  .build();

          try {
              Response response = client.newCall(request).execute();
              String jsonString = response.body().string();
              JSONArray jsonArray = new JSONArray(jsonString);

              /* ... */

          } catch (Exception e) {
              e.printStackTrace();
          }

          /* ... eventually returns a MatrixCursor */
    }

    /* ... */
}

1 个答案:

答案 0 :(得分:1)

好的,我发现这是Android调用您的提供商的一个问题,而您无法控制它如何调用它。

我也没有办法干净利落地做到这一点。可搜索与活动相关联。您可以将屏幕基于活动而不是片段(更改设计),或者做一些可怕的事情,例如在片段恢复时设置首选项,以便内容提供者知道哪个片段是“活动的”。