20

我目前的应用程序在左侧设置了ListFragment,在右侧设置了DetailsFragment(类似于以下平板电脑上的布局)。Android Actionbar搜索窗口小部件实现在ListFragment中

layout

在操作栏上我有当一个搜索词被提交应该更新列表的内容(在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"/> 

是否有可能让搜索小工具来更新当前活动的名单?

回答

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); 
} 

创建你的s小部件操作搜索通过以编程方式(爪哇)或声明(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中的私人类字段设置为当前的文字CH部件(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的人向前设置的最佳实践,(在你的ListActivity S使用LoaderManager S和ListFragments原本应是很容易为你...

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

+0

非常感谢您的详细解释,我会尽量在接下来的几天内实施它,并让您知道我是否有任何问题 – bencallis 2012-03-05 18:15:15

+0

谢谢我已经设法得到它工作非常丰富的答案有一件事,我想知道在默认情况下,我有3个标签,每个代表一个类别时,搜索我想删除这些标签。这不是一个问题,我遇到的问题是我怎么知道当用户有时完成搜索(返回)重新添加标签。 – bencallis 2012-03-07 05:00:22

+0

@bencallis你最想在SearchView上使用setOnCloseListener(SearchView.OnCloseListener监听器)... – ckozl 2012-03-07 05:22:35