如何在上下文操作栏中创建“搜索”字段?

5
我有一个带ActionBar的活动。其中之一的选项是搜索文档(不一定是本地的)。我想使用上下文操作栏(CAB)并包括以下项目:
- 编辑字段 - 为用户输入要搜索的文本的位置 - 上一个按钮 - 移至与搜索匹配的上一个项 - 下一个按钮 - 移至与搜索匹配的下一个项
我想使用CAB的原因有几个。主要是,我希望用户选择一个选项,从而带出上述定义的CAB。当用户完成搜索后,他们选择“完成”按钮,ActionBar返回到以前的状态。
问题在于,我的CAB中无法以展开的状态显示搜索项。请注意:我要修改的Activity不是主Activity,而是基于某些事件由用户启动的Activity。一旦加载了此Activity,用户可能会决定或者不决定使用我描述的“搜索”功能。我也不想让Android进行搜索。我有一个API可以搜索我想要的结果,并允许我浏览上一个/下一个搜索结果。
我的CAB代码(已正确调用)如下:
     protected ActionMode mActionModeSearch;
private ActionMode.Callback mActionModeSearchCallback = new ActionMode.Callback()
{
    @Override
    public boolean onCreateActionMode(ActionMode actionMode, Menu menu)
    {
        actionMode.getMenuInflater().inflate(R.menu.pdf_menu_search, menu);
        // Associate searchable configuration with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.pdf_menu_search_item).getActionView();
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        searchView.setIconifiedByDefault(false);
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
        {
            @Override
            public boolean onQueryTextSubmit(String s)
            {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s)
            {
                return false;
            }
        });
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode actionMode, Menu menu)
    {
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem)
    {
        switch(menuItem.getItemId())
        {
            case R.id.pdf_menu_search_prev:
                findPrevSearchResult();
                return true;
            case R.id.pdf_menu_search_next:
                findNextSearchResult();
                return true;
            default:
                return false;
        }
    }

    @Override
    public void onDestroyActionMode(ActionMode actionMode)
    {
        //resetHideToolbarsTimer();
    }
};

CAB菜单代码如下:
 <?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">
<group android:id="@+id/group_search_mode">
    <item
        android:id="@+id/pdf_menu_search_item"
        android:title="@string/search"
        android:icon="@drawable/ic_pdf_action_search"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="android.support.v7.widget.SearchView"/>
    <item
        android:id="@+id/pdf_menu_search_prev"
        android:title="@string/search_prev"
        android:icon="@drawable/ic_pdf_action_search_prev"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/pdf_menu_search_next"
        android:title="@string/search_next"
        android:icon="@drawable/ic_pdf_action_search_next"
        app:showAsAction="ifRoom" />
</group>

我还改变了AndroidManifest.xml中的活动定义,尽管我不确定这是否是必需的:

         <activity
        android:name="com.myapp.myActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data
            android:name="android.app.default_searchable"
            android:value="com.myapp.myActivity" />
        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />
    </activity>

当我运行应用程序时,活动正确加载。当用户选择搜索选项时,我加载CAB,看起来运行良好。我逐步执行代码以确保onCreateActionMode按预期工作。但是,我只看到搜索、下一个和上一个图标,以及“完成”按钮。当我点击“搜索”图标时,它什么也不做。在CAB中没有为我创建文本输入框。我做错了什么吗?截图显示CAB出现的情况。正如您所看到的,搜索图标显示,但当我按下它时没有任何反应。我真正需要的是默认情况下出现搜索编辑框。
2个回答

11

首先,我们应该为所有菜单项的app:showAsAction属性设置为always值:

<?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">
    <group android:id="@+id/group_search_mode">
        <item
            android:id="@+id/pdf_menu_search_item"
            android:icon="@drawable/ic_pdf_action_search"
            android:title="@string/search"
            app:actionViewClass="android.support.v7.widget.SearchView"
            app:showAsAction="always"/>
        <item
            android:id="@+id/pdf_menu_search_prev"
            android:icon="@drawable/ic_pdf_action_search_prev"
            android:title="@string/search_prev"
            app:showAsAction="always"/>
        <item
            android:id="@+id/pdf_menu_search_next"
            android:icon="@drawable/ic_pdf_action_search_next"
            android:title="@string/search_next"
            app:showAsAction="always"/>
    </group>
</menu>
在这种情况下,我们不需要为我们的Activity设置意图过滤器或者为我们的SearchView设置可搜索信息。
AndroidManifest.xml中定义此Activity
<activity
    android:name="com.myapp.myActivity"
    android:label="@string/app_name" />

ActionMode.Callback的实现:

private ActionMode.Callback mActionModeSearchCallback = new ActionMode.Callback() {

    private SearchView mSearchView;

    @Override
    public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
        actionMode.getMenuInflater().inflate(R.menu.home, menu);
        mSearchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.pdf_menu_search_item));
        mSearchView.setIconifiedByDefault(false);
        mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                return false;
            }
        });
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
        mSearchView.requestFocus();
        return true;
    }

    @Override
    public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
        switch (menuItem.getItemId()) {
            case R.id.pdf_menu_search_prev:
                findPrevSearchResult();
                return true;
            case R.id.pdf_menu_search_next:
                findNextSearchResult();
                return true;
            default:
                return false;
        }
    }

    @Override
    public void onDestroyActionMode(ActionMode actionMode) {

    }
};

我刚在三台安卓4.0及以上的设备上测试了这段代码,完全可用。但我没有在低版本操作系统的设备上测试过。

希望对你有所帮助。


太棒了!!!我尝试了你答案的几乎每个变化,但总是缺少一个东西。你把它们全部整合在一起了。谢谢!!! - JustLearningAgain

2

我在CAB中遇到了搜索视图的问题,所以我在菜单项中设置了一个带有EditText的布局,它给我提供了与SearchView相同的视图。你可以尝试一下,希望对你有用。

menu/search.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/edt_mySearch"
        android:actionLayout="@layout/search_bar"
        android:enabled="true"
        android:showAsAction="always"
        android:visible="true"/>

</menu>

布局/搜索栏.xml

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


    <EditText 
        android:layout_alignParentLeft="true"
        android:id="@+id/edt_search"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint=" Search..."
        />


</RelativeLayout>

和我的操作模式

mActionModeCallback = new ActionMode.Callback() {

            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                // mode.setTitle("Demo");
                getSupportMenuInflater().inflate(R.menu.search, menu);
                RelativeLayout m = (RelativeLayout) menu.findItem(
                        R.id.edt_mySearch).getActionView();
                EditText mSearchView = (EditText) m
                        .findViewById(R.id.edt_search);

                mSearchView.addTextChangedListener(new TextWatcher() {

                    @Override
                    public void onTextChanged(CharSequence s, int start,
                            int before, int count) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void beforeTextChanged(CharSequence s, int start,
                            int count, int after) {

                    }

                    @Override
                    public void afterTextChanged(Editable s) {
                        // search here
                    }
                });
                return true;
            }

            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                return false;
            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {
            }

        };

请尝试一下并回复。 - Lokesh
你的回答假设了ActionBarSherlock。我正在使用support库。你能否考虑这一点重新回答一下?我喜欢你的思路,正在尝试让它工作。 - JustLearningAgain
我添加了代码:actionMode.getMenuInflator().inflate(R.menu.search, menu)。然后我尝试获取相对布局。我在search_bar.xml中为布局添加了一个ID:android:id="@+id/pdf_search_relative_layout"。然后我调用了:RelativeLayout m = (RelativeLayout) menu.findItem(R.id.pdf_search_relative_layout); 问题是我得到了一个空的'm'。 - JustLearningAgain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接