我目前设置的应用程序左侧为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"/>
是否可以让搜索小部件更新当前活动的列表?
答案 0 :(得分: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
{1}}我只是更新我使用的查询:
@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);
}
这就是你真正需要做的事情,我意识到这有点被砍掉了但是就像这样,因为有更多东西需要发生,设置适配器,首先使用{{1}启动加载器以及需要处理的所有其他加载程序回调...但是如果你遵循android人员提出的最佳实践,(在你的getLoaderManager().initLoader(0, null, this);
和LoaderManager
中使用ListActivity
{1}}你应该很容易......
如果你需要-ck
,我希望这有助于在评论中要求澄清