20

我目前将我的应用程序设置ListFragment为左侧和DetailsFragment右侧(类似于下面平板电脑上的布局)。

布局

在操作栏上,我有一个搜索小部件,当提交搜索词时,它应该更新列表的内容(在 ListFragment 中)。我一直在关注 android dev ( http://developer.android.com/guide/topics/search/search-dialog.html ) 上的搜索指南,但在同一活动中更新列表时遇到问题。

我已经设法通过在提交搜索词时调用新活动来实现某种形式的实现,但这会使后退按钮的行为奇怪(即您按下后退并转到上一个活动,搜索小部件仍显示搜索词)。

我已将意图行添加到清单中,如下所示

<intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data android:name="android.app.searchable"
               android:resource="@xml/searchable"/>

是否可以让搜索小部件更新当前活动的列表?

4

1 回答 1

46

是的,事实上,这是“正常”用例。您必须记住的是,使用搜索操作栏小部件的片段通常应该是注册它的部分,因为小部件将与该片段一起被破坏。

以下是正确绑定它的方法:

在你ListFragment让人们知道你有选项菜单项......

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    ..
    setHasOptionsMenu(true);
    ..
}

然后在同一内部ListFragment通过覆盖回调创建您的选项菜单,一旦您拥有 SearchView 小部件引用,注册一个 QueryTextListener 回调:

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.grid_default, menu); 
    SearchView searchView = (SearchView)menu.findItem(R.id.grid_default_search).getActionView();
    searchView.setOnQueryTextListener(queryListener);
}

通过编程方式(Java)或声明方式(XML)创建您的搜索小部件,这里是 XML(命名为 grid_default.xml,来自上面):

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

    <item     
        android:id="@+id/grid_default_search"
        android:icon="@android:drawable/ic_menu_search"
        android:title="search"
        android:showAsAction="always"
        android:actionViewClass="android.widget.SearchView" 
    />

    <!-- other items or whatever  -->

</menu>

现在回到ListFragment你需要创建queryListener我们上面注册的:

private String grid_currentQuery = null; // holds the current query...

final private OnQueryTextListener queryListener = new OnQueryTextListener() {       

    @Override
    public boolean onQueryTextChange(String newText) {
        if (TextUtils.isEmpty(newText)) {
            getActivity().getActionBar().setSubtitle("List");               
            grid_currentQuery = null;
        } else {
            getActivity().getActionBar().setSubtitle("List - Searching for: " + newText);
            grid_currentQuery = newText;

        }   
        getLoaderManager().restartLoader(0, null, MyListFragment.this); 
        return false;
    }

    @Override
    public boolean onQueryTextSubmit(String query) {            
        Toast.makeText(getActivity(), "Searching for: " + query + "...", Toast.LENGTH_SHORT).show();
        return false;
    }
};

现在您知道何时更改或提交查询,在我的示例中,每当按下某个键时我都会重新查询,因为我的数据库很小且结果很快,您可能需要更改它..但是您会注意到我的情况只需使用小部件将私有类字段设置ListFragment为搜索小部件()的当前文本,grid_currentQuery然后我只是在我的getLoaderManager().restartLoader(0, null, MyListFragment.this);内部调用onCreateLoader我只是在更新我使用的查询,如下所示:

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle bargs) {

    String sort = "SortColumn ASC";
    String[] grid_columns = new String[] { "ColumnA", "ColumnB", "Etc..." };
    String grid_whereClause = "ColumnToSearchBy LIKE ?"

    if (!TextUtils.isEmpty(grid_currentQuery)) {            
        return new CursorLoader(getActivity(), DataProvider.CONTENT_URI, grid_columns, grid_whereClause, new String[] { grid_currentQuery + "%" }, sort);
    }       

    return new CursorLoader(getActivity(), DataProvider.CONTENT_URI, grid_columns, null, null, sort);
}

这就是你真正需要做的,我意识到这有点被切碎了,但它是这样的,因为还有更多的事情需要发生,设置适配器,首先使用加载器getLoaderManager().initLoader(0, null, this);和所有其余的加载器需要处理的回调...但是如果您遵循 android 人员提出的最佳实践,(在您的 s 和s 中使用LoaderManagers 对您来说应该很容易...ListActivityListFragments

如果您需要 -ck,我希望这有助于随时在评论中要求澄清

于 2012-03-05T14:23:06.767 回答