How to implement getFilter on a BaseAdapter?

前端 未结 7 814
半阙折子戏
半阙折子戏 2020-12-06 03:55

I am trying to implement a getFilter() on a base adapter to filter out search results on a List. Is there any example of how to implement a getFilter()?

MainActivity

相关标签:
7条回答
  • 2020-12-06 04:05

    General procedure

    1. Enable text filtering on your ListView
    2. Change your baseadapter to store two copies of the list, one original, one filtered.
    3. Change all access references in your BaseAdapter to refer to the Filtered list, not the original.
    4. Implement your Filter function in BaseAdapter.

    Step 1:
    listview.setTextFilterEnabled(true);

    Step 2:

    public class AppInfoAdapter extends BaseAdapter implements Filterable{
        private List mListAppInfo;
        private List mListAppInfoFiltered;
    
    public AppInfoAdapter(Context c, List list, PackageManager pm) {
        mContext = c;
        mListAppInfo = list;
        mPackManager = pm;
        mPackManagerFiltered = pm; //added line
    }
    

    Step 3:

    public int getCount() {
        return mListAppInfoFiltered.size();
    }
    public Object getItem(int position) {
        return mListAppInfoFiltered.get(position);
    }
    public View getView(int position, View convertView, ViewGroup parent) {
        // get the selected entry
        ApplicationInfo entry = (ApplicationInfo) mListAppInfoFiltered.get(position);
    

    }

    Step 4: I am not sure what type your list is, so assuming a list of String:

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                if (constraint == null || constraint.length() == 0) {
                    //no search, so just return all the data
                    results.count = mListAppInfo.size();
                    results.values = mListAppInfo;
                } else {//do the search
                    List<String> resultsData = new ArrayList<>();
                    String searchStr = constraint.toString().toUpperCase();
                    for (String s : mListAppInfo)
                            if (s.toUpperCase().contains(searchStr)) resultsData.add(s);
                        results.count = resultsData.size();
                        results.values = resultsData;
                    }
                    return results;
                }
    
                @Override
                protected void publishResults(CharSequence constraint, FilterResults results) {
                    mListAppInfoFiltered = (ArrayList<MyObject>) results.values;
                    notifyDataSetChanged();
                }
            };
        }
    }
    
    0 讨论(0)
  • 2020-12-06 04:09

    You need to return an instance of a Filter. To write a filter, subclass Filter and implement performFiltering and publishResults. See the docs.

    0 讨论(0)
  • 2020-12-06 04:17

    extend your class with ArrayAdapter,then override methods,and create object of filter class and return with it.

    0 讨论(0)
  • 2020-12-06 04:20

    this almost got me killed :)

    1. implement your BaseAdapter like this:
    2. define an ArrayList of List in your public adapter class which is gonna contain temporary items of your Original List.

      public class MyAdapter extends BaseAdapter implements Filterable{
      
          public static ArrayList<String> temporarylist;
          public static ArrayList<String> OriginalList;
          private Activity activity;
      
          public MyAdapter(Activity activity, ArrayList<String> OriginalList) {
               super();
               this.activity=activity;
               this.OriginalList = OriginalList;
               temporarylist=OriginalList;
      
          }
          .
          .
          .
      
    3. create getFilter() method with the following code[as an example]:

      public Filter getFilter() {
          Filter filter = new Filter() {
      
          @SuppressWarnings("unchecked")
          @Override
          protected void publishResults(CharSequence constraint, FilterResults results) {
              temporarylist=(ArrayList<String>)results.values;
              notifyDataSetChanged();
          }
      
          @Override
          protected FilterResults performFiltering(CharSequence constraint) {
              FilterResults results = new FilterResults();
              ArrayList<String> FilteredList= new ArrayList<String>();
              if (constraint == null || constraint.length() == 0) {
                  // No filter implemented we return all the list
                  results.values = OriginalList;
                  results.count = OriginalList.size();
              }
              else {
                  for (int i = 0; i < OriginalList.size(); i++) {
                      String data = OriginalList.get(i);
                      if (data.toLowerCase().contains(constraint.toString()))  {
                          FilteredList.add(data);
                      }
                  }
                  results.values = FilteredList;
                  results.count = FilteredList.size();
              }
              return results;
          }
      };
      return filter;
      }
      

    And finally in your activity for your EditText:

    MyAdapter adapter;
    ArrayList<String> items;
    
    
    ListView list = (ListView) findViewById(R.id.list);
    items = new ArrayList<String>();
    for (int i=0;i<30;i++){
         items.add("Hello world "+String.valueof(i));
    }
    adapter = new GameAdapter(this, items);
    list.setAdapter(adapter);
    
    
    EditText inputSearch = (EditText) findViewById(R.id.Search_txt);
         inputSearch.addTextChangedListener(new TextWatcher() {
    
                @Override
                public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                    // When user changed the Text
                    MyActivity.this.adapter.getFilter().filter(cs);
                }
    
                @Override
                public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                        int arg3) {
                    // TODO Auto-generated method stub
    
                }
    
                @Override
                public void afterTextChanged(Editable arg0) {
                    // TODO Auto-generated method stub                          
                }
            });
    
    0 讨论(0)
  • 2020-12-06 04:21

    Can you post your full AppInfoAdapter? Also is there any reason extending from BaseAdapter and not ArrayAdapter? If you have an ArrayList of objects, use ArrayAdapter, it already implements Filterable interface.

    Actually you are using a List, your adapter can be rewritten to extends ArrayAdapter which already is Filterable.

    public class AppInfoAdapter extends ArrayAdapter<ApplicationInfo> {
    
        private Context mContext;
        PackageManager mPackManager;
    
        public AppInfoAdapter(Context c, List<ApplicationInfo> list, PackageManager pm) {
            super(c, 0, new ArrayList<ApplicationInfo>());
            mContext = c;
            mPackManager = pm;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // get the selected entry
            ApplicationInfo entry = (ApplicationInfo) getItem(position);
    
            // reference to convertView
            View v = convertView;
    
            // inflate new layout if null
            if(v == null) {
                LayoutInflater inflater = LayoutInflater.from(mContext);
                v = inflater.inflate(R.layout.layout_appinfo, null);
            }
    
            // load controls from layout resources
            ImageView ivAppIcon = (ImageView)v.findViewById(R.id.ivIcon);
            TextView tvAppName = (TextView)v.findViewById(R.id.tvName);
            TextView tvPkgName = (TextView)v.findViewById(R.id.tvPack);
    
            // set data to display
            ivAppIcon.setImageDrawable(entry.loadIcon(mPackManager));
            tvAppName.setText(entry.loadLabel(mPackManager));
            tvPkgName.setText(entry.packageName);
    
            // return view
            return v;
        }
    }
    
    0 讨论(0)
  • 2020-12-06 04:23

    getFilter() can be override in adapters and return the filter object which contains filtered list . There are two key methods in Filter() class; performFiltering and publishResults. The first method performs the filtering in worker thread and the later one return filtered list of objects.

    You can refer to sample code below

    @Override
    public Filter getFilter() {
    
            return new Filter() {
    
                @Override
                protected void publishResults(CharSequence constraint, FilterResults results) {
                    // TODO Auto-generated method stub
                    if (results.count == 0) {
                        notifyDataSetInvalidated();
                    }else{
                        mListAppInfo = (ArrayList<SampleItem>) results.values;
                        notifyDataSetChanged();
                    }
                }
    
                @Override
                protected FilterResults performFiltering(CharSequence constraint) {
                    // TODO Auto-generated method stub
                    FilterResults results = new FilterResults();
    
                    if (constraint == null || constraint.length() == 0) {
                        results.values = mListAppInfo;
                        results.count = mListAppInfo.size();
                    }else{
                        ArrayList<SampleItem> filter_items = new ArrayList<>(); 
                        for (SampleItem item : mListAppInfo) {
                            if (item.getItemName().toLowerCase().startsWith(constraint.toString().toLowerCase())) {
                                filter_items.add(item);
                            }
                        }
                        results.values =  filter_items ;
                        results.count = filter_items.size();
                    }
                    return results;
                }
            };
        }
    

    Hope you find it useful .

    0 讨论(0)
提交回复
热议问题