如何在工具栏 Android 中使用 SearchView

Posted

技术标签:

【中文标题】如何在工具栏 Android 中使用 SearchView【英文标题】:How to use SearchView in Toolbar Android 【发布时间】:2015-02-07 08:20:11 【问题描述】:

我正在处理的代码是使用Toolbar 并膨胀menu

这里是代码

private Toolbar mToolbar;
mToolbar.inflateMenu(R.menu.chat_screen_menu);
setupMenu ();
private void setupMenu ()
   
   mMenu = mToolbar.getMenu();
   if (mMenu != null)
      
       if (mChatPager != null && mChatPager.getCurrentItem() > 0)
          
          mMenu.setGroupVisible(R.id.menu_group_chats, true);
          mMenu.setGroupVisible(R.id.menu_group_contacts, false);
          
       else
          
           mMenu.setGroupVisible(R.id.menu_group_chats, false);
           mMenu.setGroupVisible(R.id.menu_group_contacts, true);
           mMenu.setGroupVisible(R.id.menu_group_otr_verified,false);
           mMenu.setGroupVisible(R.id.menu_group_otr_unverified,false);
           mMenu.setGroupVisible(R.id.menu_group_otr_off,false);
          
    
    mToolbar.setOnMenuItemClickListener(new OnMenuItemClickListener ()
    
    ..........
    

但现在,他们需要在 tool_bar 中添加一个 Search 按钮。 我设法把它说出来,我跟着一个指南here 当我尝试写一些东西来搜索时,我用来测试listener 的吐司从未出现过。 这表明listener 不工作

@Override
    public boolean onCreateOptionsMenu(Menu menu) 

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.chat_screen_menu, menu);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    mSearchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_menu_search));
    final Toast toast = new Toast(mApp);

    if (mSearchView != null )
    
        mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        mSearchView.setIconifiedByDefault(false);

        SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener()
        
            public boolean onQueryTextChange(String newText)
            
                mSearchString = newText;
                //doFilterAsync(mSearchString);
                toast.makeText(getApplicationContext(), "Test1", Toast.LENGTH_LONG).show();
                return true;
            

            public boolean onQueryTextSubmit(String query)
            
                mSearchString = query;
                //doFilterAsync(mSearchString);
                toast.makeText(getApplicationContext(), "Test2", Toast.LENGTH_LONG).show();

                return true;
            
        ;

        mSearchView.setOnQueryTextListener(queryTextListener);
    

    return true;


【问题讨论】:

【参考方案1】:

为此,您必须使用 Appcompat 库。使用如下:

dashboard.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android" 
      xmlns:tools="http://schemas.android.com/tools"
      xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_search"
        android:icon="@android:drawable/ic_menu_search"
        app:showAsAction="always|collapseActionView"
        app:actionViewClass="androidx.appcompat.widget.SearchView"
        android:title="Search"/>
</menu>

活动文件(Java):

public boolean onCreateOptionsMenu(Menu menu) 
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.dashboard, menu);

     MenuItem searchItem = menu.findItem(R.id.action_search);

    SearchManager searchManager = (SearchManager) MainActivity.this.getSystemService(Context.SEARCH_SERVICE);

    SearchView searchView = null;
    if (searchItem != null) 
        searchView = (SearchView) searchItem.getActionView();
    
    if (searchView != null) 
        searchView.setSearchableInfo(searchManager.getSearchableInfo(MainActivity.this.getComponentName()));
    
        return super.onCreateOptionsMenu(menu);

活动文件(在 Kotlin 中):

override fun onCreateOptionsMenu(menu: Menu?): Boolean 
    menuInflater.inflate(R.menu.menu_search, menu)

    val searchItem: MenuItem? = menu?.findItem(R.id.action_search)
    val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
    val searchView: SearchView? = searchItem?.actionView as SearchView

    searchView?.setSearchableInfo(searchManager.getSearchableInfo(componentName))
    return super.onCreateOptionsMenu(menu)

清单文件:

<meta-data 
      android:name="android.app.default_searchable" 
      android:value="com.apkgetter.SearchResultsActivity" /> 

        <activity
            android:name="com.apkgetter.SearchResultsActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop" >
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
            </intent-filter>

            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>

可搜索的 xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:hint="@string/search_hint"
    android:label="@string/app_name" />

最后,您的SearchResultsActivity 课程代码。用于显示您的搜索结果。

【讨论】:

注意现在你应该import android.support.v7.widget.SearchView 谢谢,您知道如何处理“开始”点击吗?这会有所帮助 我将只链接官方文档,您还可以在其中找到如何响应查询developer.android.com/training/search/setup.html 注意 app:actionViewClass 而不是 android:actionViewClass 如果您已迁移到 androidX,请使用:androidx.appcompat.widget.SearchView【参考方案2】:

如果您想在 Fragment 中设置搜索工具,只需添加以下几行:

第 1 步 - 将搜索字段添加给您toolbar

<item
    android:id="@+id/action_search"
    android:icon="@android:drawable/ic_menu_search"
    app:showAsAction="always|collapseActionView"
    app:actionViewClass="android.support.v7.widget.SearchView"
    android:title="Search"/>

第 2 步 - 将逻辑添加到您的 onCreateOptionsMenu()

import android.support.v7.widget.SearchView; // not the default !

@Override
public boolean onCreateOptionsMenu( Menu menu) 
    getMenuInflater().inflate( R.menu.main, menu);

    MenuItem myActionMenuItem = menu.findItem( R.id.action_search);
    searchView = (SearchView) myActionMenuItem.getActionView();
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() 
        @Override
        public boolean onQueryTextSubmit(String query) 
            // Toast like print
            UserFeedback.show( "SearchOnQueryTextSubmit: " + query);
            if( ! searchView.isIconified()) 
                searchView.setIconified(true);
            
            myActionMenuItem.collapseActionView();
            return false;
        
        @Override
        public boolean onQueryTextChange(String s) 
            // UserFeedback.show( "SearchOnQueryTextChanged: " + s);
            return false;
        
    );
    return true;

【讨论】:

如果您不想在用户提交搜索查询时创建/移动到新活动,此答案会更有帮助。这将允许您停留在相同的活动/片段上,并且只需根据用户输入更新视图。很棒的东西。 UserFeedback ... 是我的 Toast-alike 方法。 搜索视图中未采用键盘输入 R.menu.main 是什么? public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) 你可以在这里直接调用这个方法你可以infilate自己的菜单,并且直接从fragment处理这个而不使用activity。很好,谢谢【参考方案3】:

如果你想直接在工具栏中添加。

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_>

    <android.support.v7.widget.Toolbar
        android:id="@+id/app_bar"
        android:layout_
        android:layout_>

        <SearchView
            android:id="@+id/searchView"
            android:layout_
            android:layout_
            android:iconifiedByDefault="false"
            android:queryHint="Search"
            android:layout_centerHorizontal="true" />

    </android.support.v7.widget.Toolbar>

</android.support.design.widget.AppBarLayout>

【讨论】:

如果您使用支持 SearchView,请不要忘记在 XML 中也将其声明为android.support.v7.widget.SearchView 别忘了在gradle中添加implementation 'com.android.support:design:$latest_version' 什么是图标化 ¨如果您希望搜索字段始终可见,请从文档中调用 setIconifiedByDefault(false)¨【参考方案4】:

将 SearchView 与 RecyclerView 集成

1) 在菜单中添加 SearchView 项

SearchView 可以在菜单中添加为actionView

app:useActionClass = "android.support.v7.widget.SearchView" .

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="rohksin.com.searchviewdemo.MainActivity">
<item
    android:id="@+id/searchBar"
    app:showAsAction="always"
    app:actionViewClass="android.support.v7.widget.SearchView"
    />
</menu>

2) 在 Activity 中实现 SearchView.OnQueryTextListener

SearchView.OnQueryTextListener 有两个抽象方法。因此,在实现 SearchView 文本侦听器之后,您的活动框架现在看起来像这样。

YourActivity extends AppCompatActivity implements SearchView.OnQueryTextListener

   public boolean onQueryTextSubmit(String query)

   public boolean onQueryTextChange(String newText) 


3) 设置 SerchView 提示文本、监听器等

@Override
public boolean onCreateOptionsMenu(Menu menu) 
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);

    MenuItem searchItem = menu.findItem(R.id.searchBar);

    SearchView searchView = (SearchView) searchItem.getActionView();
    searchView.setQueryHint("Search People");
    searchView.setOnQueryTextListener(this);
    searchView.setIconified(false);

    return true;

4) 实现 SearchView.OnQueryTextListener

这是实现监听器抽象方法的方法。

@Override
public boolean onQueryTextSubmit(String query) 

    // This method can be used when a query is submitted eg. creating search history using SQLite DB

    Toast.makeText(this, "Query Inserted", Toast.LENGTH_SHORT).show();
    return true;


@Override
public boolean onQueryTextChange(String newText) 

    adapter.filter(newText);
    return true;

5) 在您的 RecyclerView Adapter 中编写一个过滤器方法。

您可以根据自己的要求提出自己的逻辑。这是示例代码 sn-p 显示名称列表,其中包含在SearchView 中键入的文本。

public void filter(String queryText)

    list.clear();

    if(queryText.isEmpty())
    
        list.addAll(copyList);
    
    else
    

        for(String name: copyList)
        
            if(name.toLowerCase().contains(queryText.toLowerCase()))
            
                list.add(name);
            
        

    

    notifyDataSetChanged();

可以找到完整的工作代码示例>HERE 您还可以在 Music App 中使用 SQLite 数据库查看 SearchView 上的代码

【讨论】:

为什么需要菜单?【参考方案5】:

在不使用menu.xml文件的情况下实现SearchView并通过按钮打开

在您的Activity 中,我们需要使用onCreateOptionsMenumethod 的方法,我们将以编程方式对SearchView 进行膨胀

private MenuItem searchMenu;
private String mSearchString="";

@Override
    public boolean onCreateOptionsMenu(Menu menu) 
        super.onCreateOptionsMenu(menu);

        SearchManager searchManager = (SearchManager) StoreActivity.this.getSystemService(Context.SEARCH_SERVICE);


        SearchView mSearchView = new SearchView(getSupportActionBar().getThemedContext());
        mSearchView.setQueryHint(getString(R.string.prompt_search)); /// YOUR HINT MESSAGE
        mSearchView.setMaxWidth(Integer.MAX_VALUE);

        searchMenu = menu.add("searchMenu").setVisible(false).setActionView(mSearchView);
        searchMenu.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);


        assert searchManager != null;
        mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        mSearchView.setIconifiedByDefault(false);

        SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() 
            public boolean onQueryTextChange(String newText) 
                mSearchString = newText;

                return true;
            

            public boolean onQueryTextSubmit(String query) 
                mSearchString = query;

                searchMenu.collapseActionView();


                return true;
            
        ;

        mSearchView.setOnQueryTextListener(queryTextListener);


        return true;
    

在您的 Activity 类中,您可以在工具栏上的任何按钮上打开SearchView,如下所示

YOUR_BUTTON.setOnClickListener(view -> 

            searchMenu.expandActionView();

        );

【讨论】:

【参考方案6】:

我搜索并实现了很多代码,但这对我不起作用。 然后我在我的 XML 文件中实现自定义工具栏,然后在工具栏标记内使用 searchview 标记。 希望它对你有用。

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于如何在工具栏 Android 中使用 SearchView的主要内容,如果未能解决你的问题,请参考以下文章

如何在工具栏 Android 中使用 SearchView

如何在android中隐藏工具栏?

如何在Mac中使用Android SDK,使用adb工具避免出现

在Android的Strings.xml中该如何使用&

Android如何使用工具栏中的按钮切换以使用片段打开/关闭导航抽屉

如何在 Android 中实际使用 Material Design 工具生成的调色板?