如何将搜索功能添加到 Listview 中?

How to add search functionality into Listview?

我在使用搜索栏时遇到了一些问题。 我有一个应用程序在某些 activity 中有一个列表视图,列表视图里面只有字符串。我想在此 activity 中添加搜索功能。 在过去的几天里,我在网上搜索了一些如何做到这一点的例子,我找到了很多关于如何创建搜索栏的指南和解释,其中 none 个在我的应用程序中正常工作在其中的大多数中,没有解释那里发生的事情背后的逻辑。

是否有任何简单的 guide/tutorial 可以解释如何创建搜索栏(不管它是在操作栏上还是在布局中),这将减少已经存在的列表视图字符串到更小的列表? (例如,如果您键入字母 "a",那么将显示列表视图中包含字母 "a" 的所有字符串)。

提前致谢!

以下代码将帮助您过滤 listView 的内容。

  1. 使用如下布局创建 SearcView:

        <ImageView
            android:id="@+id/icon_search"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="8dp"
            android:src="@drawable/icon_search" />
    
        <EditText
            android:id="@+id/et_userInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:background="@null"
            android:hint="@string/search_friends_and_contacts"
            android:singleLine="true"
            android:textColor="@color/white"
            android:textColorHint="@color/white"
            android:textSize="14sp" />
    
        <ImageView
            android:id="@+id/icon_close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="8dp"
            android:src="@drawable/icon_close_white" />
    

将其包含在您的列表视图布局中。

  1. 更新您的适配器 class:

使用 Filterable 实现您的适配器 class。并覆盖 getFilter 方法并在您的 getFilter 方法中编写此代码:

private SearchFilter mSearchFilter ;

 @Override
    public Filter getFilter() {
        if (mSearchFilter == null) {
            mSearchFilter = new SearchFilter();
        }
        return mSearchFilter;
    }

现在在扩展过滤器的适配器中创建内部私有 class:

私有 class SearchFilter 扩展过滤器 {

//Invoked in a worker thread to filter the data according to the constraint.
@Override
protected FilterResults performFiltering(CharSequence constraint) {
    FilterResults results = new FilterResults();
    if (constraint != null && constraint.length() > 0) {
        ArrayList<String> filterList = new ArrayList<FriendsModel>();
        for (int i = 0; i < mOriginalList.size(); i++) {
            if ((mOriginalList.get(i).toUpperCase())
                    .contains(constraint.toString().toUpperCase())) {
                filterList.add(mOriginalList.get(i));
            }
        }
        results.count = filterList.size();
        results.values = filterList;
    } else {
        results.count = mOriginalList.size();
        results.values = mOriginalList;
    }
    return results;
}


//Invoked in the UI thread to publish the filtering results in the user interface.
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
                              FilterResults results) {
    mListViewArrayList = (ArrayList<String>) results.values;
    notifyDataSetChanged();
    }
}

还在你的适配器中定义两个 ArrayListVariable class 像这样:

ArrayList<String> mListViewArrayList ; <----- which will be used to render data from getView Method
ArrayList<String> mOriginalList ; <----- Which holds original list all the time.

要从 activity 调用此过滤器,请在 Activity 中编写以下代码:

et_userInput.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                yourAdapter.getFilter().filter(arg0);
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                                          int arg3) {
            }

            @Override
            public void afterTextChanged(Editable arg0) {

            }
        });