android - 在操作栏中实现 SearchView

标签 android android-actionbar autocompletetextview searchview

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

enter image description here

我正在寻找逐步解释如何构建 SearchView 的教程。在操作栏中。

我已阅读 the documentation并按照示例谷歌,但它对我没有用。

我已经创建了搜索

<?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>`

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

最佳答案

为此制定解决方案需要一段时间,但发现这是使其以您描述的方式工作的最简单方法。可能有更好的方法来做到这一点,但由于您尚未发布您的 Activity 代码,我将不得不即兴发挥并假设您在 Activity 开始时有这样的列表:

private List<String> items = db.getItems();

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

    }

}

现在你需要创建一个扩展自 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;

    }

}

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

请注意:导入CursorAdapter时不要导入Android支持版本,而是导入标准的android.widget.CursorAdapter

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

res/layout/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>

您现在可以通过向布局添加额外的文本或 ImageView 并使用适配器中的数据填充它们来自定义列表项。

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

res/menu/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>

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

res/xml/searchable.xml

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search"
    android:hint="@string/search" >
</searchable>

最后在 list 文件的相关 Activity 标签中添加这个:

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" />

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

关于android - 在操作栏中实现 SearchView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21585326/

相关文章:

android - AdMob推广中DisplayUrl要放什么?

java - JSON 解析花费太多时间 - Android

java - 在 android studio 中单击操作栏菜单中的项目时跳转到另一个 Activity

android - 为什么 AutoCompleteTextView 上的 getText() 和 getEditableText() 总是产生一个空字符串?

java - 如何解决 "The content of the adapter has changed but ListView did not receive a notification”异常

java - 对 android 编程,当我构建项目时,我的布局 xml 文件不会更新

android - 通过样式更改操作栏溢出菜单项的高度

java - 如何使用attach()和detach()而不是add()和remove()来保存 fragment View

android - 两个或多个 AutoCompleteTextView 不工作

Java Android - CSVWriter 使用特定单元格计算数学公式