在操作栏中实现SearchView

Mat*_*teo 79 android autocompletetextview android-actionbar searchview

我需要SearchView从我的创建arrayList<String>并在下拉列表中显示相同的建议

在此输入图像描述

我寻找教程,逐步解释如何SearchView在操作栏中构建一个.

我已经阅读了文档,并按照谷歌的例子,但它对我没用.

我创建了搜索

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/action_search"
          android:title="Search"
          android:icon="@android:drawable/ic_menu_search"
          android:showAsAction="always"
          android:actionViewClass="android.widget.SearchView" />
</menu>`
Run Code Online (Sandbox Code Playgroud)

但我不知道如何设置字符串数组的参数.我试图在不同的Activity中检索结果但不起作用.

tpb*_*app 126

花了一段时间才为此制定解决方案,但发现这是让它以您描述的方式工作的最简单方法.可能有更好的方法来做到这一点,但由于你还没有发布你的活动代码,我将不得不即兴发挥并假设你在活动开始时有这样的列表:

private List<String> items = db.getItems();
Run Code Online (Sandbox Code Playgroud)

ExampleActivity.java

private List<String> items;

private Menu menu;

@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.example, menu);

    this.menu = menu;

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();

        search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));

        search.setOnQueryTextListener(new OnQueryTextListener() { 

            @Override 
            public boolean onQueryTextChange(String query) {

                loadHistory(query);

                return true; 

            } 

        });

    }

    return true;

}

// History
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void loadHistory(String query) {

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        // Cursor
        String[] columns = new String[] { "_id", "text" };
        Object[] temp = new Object[] { 0, "default" };

        MatrixCursor cursor = new MatrixCursor(columns);

        for(int i = 0; i < items.size(); i++) {

            temp[0] = i;
            temp[1] = items.get(i);

            cursor.addRow(temp);

        }

        // SearchView
        SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        final SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();

        search.setSuggestionsAdapter(new ExampleAdapter(this, cursor, items));

    }

}
Run Code Online (Sandbox Code Playgroud)

现在您需要创建一个从CursorAdapter以下扩展的适配器:

ExampleAdapter.java

public class ExampleAdapter extends CursorAdapter {

    private List<String> items;

    private TextView text;

    public ExampleAdapter(Context context, Cursor cursor, List<String> items) {

        super(context, cursor, false);

        this.items = items;

    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        text.setText(items.get(cursor.getPosition()));

    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View view = inflater.inflate(R.layout.item, parent, false);

        text = (TextView) view.findViewById(R.id.text);

        return view;

    }

}
Run Code Online (Sandbox Code Playgroud)

更好的方法是,如果列表数据来自数据库,则可以Cursor直接将数据库函数返回,ExampleAdapter并使用相关列选择器显示TextView适配器中引用的列文本.

请注意:导入时CursorAdapter请勿导入Android支持版本,请导入标准android.widget.CursorAdapter.

适配器还需要自定义布局:

RES /布局/ item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView
        android:id="@+id/item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

您现在可以通过向布局添加其他文本或图像视图并使用适配器中的数据填充它们来自定义列表项.

这应该是全部,但如果你还没有这样做,你需要一个SearchView菜单项:

RES /菜单/的example.xml

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

    <item
        android:id="@+id/search"
        android:title="@string/search"
        android:showAsAction="ifRoom"
        android:actionViewClass="android.widget.SearchView" />

</menu>
Run Code Online (Sandbox Code Playgroud)

然后创建一个可搜索的配置:

RES/XML/searchable.xml

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search"
    android:hint="@string/search" >
</searchable>
Run Code Online (Sandbox Code Playgroud)

最后在清单文件中的相关活动标记内添加:

AndroidManifest.xml中

<intent-filter>
    <action android:name="android.intent.action.SEARCH" />
</intent-filter>

<meta-data
    android:name="android.app.default_searchable"
    android:value="com.example.ExampleActivity" />
<meta-data
    android:name="android.app.searchable"
    android:resource="@xml/searchable" />
Run Code Online (Sandbox Code Playgroud)

请注意:@string/search示例中使用的字符串应在values/strings.xml中定义,也不要忘记更新com.example项目的引用.

  • 嗨,但有一点疑问,我希望你能帮助我.如果我在过滤器上键入一个字母,虽然我有过滤结果,但如果它超过一个,则不显示任何内容.然后只显示.为什么? (3认同)
  • @tpbapp我已经弄清楚了.建议列表没有出现的原因是因为在你的代码中你有`search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));`在`onCreateOptionsMenu()`和`loadHistory()`方法中调用了两次.所以我创建了SearchView和SearchManager全局变量,并且在`onCreateOptionsMenu()`中只调用了一次`getSearchableInfo()`.我的建议清单现在正在完美运作.我建议你修改你的代码. (3认同)

Gre*_*ase 49

如果其他人在searchview变量上有nullptr,我发现项目设置有点不同:

旧:

android:showAsAction="ifRoom"
android:actionViewClass="android.widget.SearchView"
Run Code Online (Sandbox Code Playgroud)

新:

app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="androidx.appcompat.widget.SearchView"
Run Code Online (Sandbox Code Playgroud)

pre-android x:

app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"
Run Code Online (Sandbox Code Playgroud)

有关更多信息,它的更新文档位于此处.

  • 谢谢.正是我所缺少的.:-) (2认同)

Roh*_*ngh 5

搜索对话框还是搜索小部件?

在实现搜索功能时,官方 Android 开发人员文档建议了两种方法。
您可以使用SearchDialogSearchWidget
我将解释使用 SearchWidget 实现搜索功能。

如何使用搜索小部件来做到这一点?

我将使用 SearchWidget 解释 RecyclerView 中的搜索功能。这非常简单。

只需遵循以下 5 个简单步骤

1)在菜单中添加searchView项

您可以添加SearchView可以添加为actionView菜单中使用

应用程序: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>
Run Code Online (Sandbox Code Playgroud)

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

您应该在onCreateOptionsMenu(Menu menu)方法中初始化 SearchView。

  @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;
   }
Run Code Online (Sandbox Code Playgroud)

3) 在您的 Activity 中实现 SearchView.OnQueryTextListener

OnQueryTextListener有两个抽象方法

  1. onQueryTextSubmit(String query)
  2. onQueryTextChange(String newText

所以你的活动骨架看起来像这样

YourActivity extends AppCompatActivity implements SearchView.OnQueryTextListener{

     public boolean onQueryTextSubmit(String query)

     public boolean onQueryTextChange(String newText) 

}
Run Code Online (Sandbox Code Playgroud)

4)实现SearchView.OnQueryTextListener

您可以像这样提供抽象方法的实现

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;
}
Run Code Online (Sandbox Code Playgroud)

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

最重要的部分。您可以编写自己的逻辑来执行搜索。
这是我的。此代码片段显示了名称列表,其中包含在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();
}
Run Code Online (Sandbox Code Playgroud)

相关链接:

此音乐应用程序中带有 SQLite 数据库的 SearchView 的完整工作代码