Android的动作条搜索插件实现在ListFragment插件、动作、Android、ListFragment

2023-09-12 02:24:36 作者:[]~就风⌒饮酒

目前,我有我的应用程序设置了一个 ListFragment 在右边的左边和 DetailsFragment (类似到下面的片剂的布局)。

I currently have my application set up with a ListFragment on the left and a DetailsFragment on the right (similar to the layout on the tablet below).

在操作栏我有当搜索字词提交应该更新列表的内容(在ListFragment)搜索小插件。 我一直关注的Andr​​oid开发(http://developer.android.com/guide/topics/search/search-dialog.html)搜索指南,但我有问题,让搜索更新列表中相同的活动。

On the action bar I have a search widget which when a search term is submitted should update the contents of the list (in the ListFragment). I have been following the search guide on android dev (http://developer.android.com/guide/topics/search/search-dialog.html) but I am having problems getting the search to update the list in the same activity.

我设法得到某种形式的实现,通过调用时的搜索字词提交了一份新的活动的工作,但是这使得后退按钮行为古怪(即你preSS回来,你到了previous活动与搜索窗口小部件仍显示搜索词)。

I have managed to get some form of implementation working by calling a new activity when the search term is submitted but this makes the back button behave oddly (i.e. you press back and you go to the previous activity with the search widget still displaying the search term).

我已经加入的意图行清单如下:

I have added the intent lines to the manifest as follows

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

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

Is it possible to get the search widget to update the list of the current activity?

推荐答案

是的,事实上,这是正常的用例。什么,你必须记住的是,使用搜索操作栏插件的片段,应该是登记在一般情况下,因为小部件会相处的片段被破坏的部分。

Yes, as a matter of fact, that is the "normal" use case. What you have to remember is that the fragment that uses the search action bar widget, should be the part that registers it in general, since the widget will get destroyed along with that fragment.

下面是如何正确地配合起来:

Here's how to properly tie it up:

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

in your ListFragment let it be known that you have option menu items...

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

那么同样 ListFragment 通过重写回调创建选项菜单,一旦你有搜索查看部件引用,注册QueryTextListener回调里面:

then inside the same ListFragment create your options menu by overriding the callback, once you have the SearchView widget reference, register a QueryTextListener callback:

@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,从上面):

create your search widget via either programmatically (Java) or declaratively (XML) here is XML (named grid_default.xml, from above):

<?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 我们上述注册:

now back in your ListFragment you need to create the queryListener we registered above:

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

现在你知道当一个查询被更改或提交的,以我为例,我重新查询随时随地一键pressed,因为我的数据库是小,快与结果,您可能需要改变这种..但你会注意到我是如何只使用小工具来设置私有类领域的 ListFragment 里面的搜索窗口小部件的当前文本( grid_currentQuery ),然后我打电话 getLoaderManager()restartLoader(0,空,MyListFragment.this); 其中,在我的 onCreateLoader 我只是更新我用这样的查询:

now you know when a query is changed or submitted, in my example, I re-query anytime a key is pressed because my database was small and fast with results, you might need to change this.. but you'll notice how I am just using the widget to set a private class field inside the ListFragment to the current text of the search widget (grid_currentQuery) and then I am just calling getLoaderManager().restartLoader(0, null, MyListFragment.this); where inside my onCreateLoader I am just updating the query I used like this:

@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,空,这一点); 和需要处理的装载机回调中的其他一切...但如果​​你是以下设置期待的最佳做法Android的人,(使用 LoaderManager 在你 ListActivity ListFragments 原本应pretty的方便你...

and that's all you really need to do, I realize this is kind of chopped up but it's like this because there is more stuff that needs to happen, setting the adapter, starting the loader in the first place using getLoaderManager().initLoader(0, null, this); and all the rest of the loader callbacks that need to be handled... but if you are following the best practices set forward by the android folks, (using LoaderManagers in your ListActivitys and ListFragmentss it should be pretty easy for you...

我希望这有助于随时要求澄清的意见,如果你需要-ck

I hope this helps feel free to ask for clarification in the comments if you need to -ck