如何在Listview中添加搜索功能?

时间:2015-11-20 08:38:19

标签: android listview searchbar

我在搜索栏中遇到了一些问题。 我有一个应用程序在某些活动中有一个Listview,列表视图中只有字符串。我想在此活动中添加搜索功能。 在过去的几天里,我在网上搜索了一些如何做到这一点的例子,并且我创建了许多关于如何创建搜索栏的指南和解释,并且它们都没有正确地在我的应用程序中正常工作他们没有解释正在发生的事情背后的逻辑。

是否有任何简单的指南/教程可以解释如何创建搜索栏(如果它将位于操作栏或布局中并不重要),这会将现有的字符串列表视图减少为小名单? (例如,如果您键入字母" a"那么列表视图中包含字母" a"的所有字符串都将显示在其中。

提前致谢!

1 个答案:

答案 0 :(得分:2)

以下代码将帮助您过滤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" />
    

  2. 在listview布局中包含此内容。

    1. 更新适配器类:
    2. 使用Filterable实现您的适配器类。并覆盖getFilter方法并在getFilter方法中编写此代码:

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

      现在在适配器中创建内部私有类,扩展了Filter:

      私有类SearchFilter扩展了Filter {

      //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,如下所示:

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

      要从活动中调用此过滤器,请在您的活动中编写以下代码:

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