Android 自定义Adapter实现模糊查询

  • 目标    Adapter可以适配AutoCompleteTextView实现模糊查询自动补全功能,相比简陋的                   ArrayAdapter而言,SimpleAdapter可实现布局功能更加复杂的任务,但                     SimpleAdapter并不能实现我们自己想要的筛选方式,所以我们可继承SimpleAdapter               实现自定义过滤器的Adapter。

  • 效果    

  • 实现策略   

             1、   自定义Adapter

                     由于SimpleAdapter复杂布局功能足够强大,所以只需要继承SimpleAdapter即可,无

                     需从头继承BaseAdapter并实现Filterable接口。在继承SimpleAdapter后,首先要

                     重写getFilter()方法。该方法返回一个内部过滤器类Filter。

public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new MySmipleFilter();
        }
        return mFilter;
    }

                    getFilter()方法供AutoCompleteTextView调用。

private AutoCompleteTextView acv;
acv = findViewById(R.id.acv);
acv.setAdapter(mySimpleAdapter);

#AutoCompleteTextView源码
public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
        if (mObserver == null) {
            mObserver = new PopupDataSetObserver(this);
        } else if (mAdapter != null) {
            mAdapter.unregisterDataSetObserver(mObserver);
        }
        mAdapter = adapter;
        if (mAdapter != null) {
            //noinspection unchecked
            mFilter = ((Filterable) mAdapter).getFilter();
            adapter.registerDataSetObserver(mObserver);
        } else {
            mFilter = null;
        }

        mPopup.setAdapter(mAdapter);
    }

                  所以我们必须要在自定义Adapter中实现一个继承自Filter类的内部类,并重写其中的

                  两个最重要的方法performFiltering(CharSequence prefix)和

                  publishResults(CharSequence constraint, FilterResults results)。前者中完成自定义的

                  模糊查询过滤规则(写我们的业务逻辑代码);后者主要负责过滤后数据条目的刷新显

                  示,切记不能使用mData = results.values;这样会使mData的引用对象发生变化,导致

                  Adapter绑定数据始终是原始数据,不能刷新成功。所以要在mData原内存中改变数

                  据。

private class MySmipleFilter extends Filter{

        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            FilterResults results = new FilterResults();

            if (mUnfilteredData == null) {
                mUnfilteredData = new ArrayList<Map<String, ?>>(mData);
            }

            if (prefix == null || prefix.length() == 0) {
                ArrayList<Map<String, ?>> list = mUnfilteredData;
                results.values = list;
                results.count = list.size();
            } else {
                String prefixString = prefix.toString().toLowerCase();

                ArrayList<Map<String, ?>> unfilteredValues = mUnfilteredData;
                int count = unfilteredValues.size();

                ArrayList<Map<String, ?>> newValues = new ArrayList<Map<String, ?>>(count);


                #自定义筛选逻辑
                for (int i = 0; i < count; i++) {
                    Map<String, ?> h = unfilteredValues.get(i);
                    if (h != null) {

                        int len = mTo.length;
                        String words = (String)h.get(mFrom[1]);
                        if (words.toLowerCase().contains(prefixString)) {
                                    newValues.add(h);
                                }

                    }
                }

                results.values = newValues;
                results.count = newValues.size();
            }

            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

            #切记不能使用mData = results.values;这样会使mData的引用对象发生变化,导致Adapter
            绑定数据始终是原始数据,不能刷新成功。所以要在mData原内存中改变数据。

            mData.clear();
            List<Map<String, Object>> mData_ = (List<Map<String, Object>>) results.values;
            mData.addAll(mData_);
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }

        }
    }

         

              2、设置监听器

                    为了实现点击后自动补全功能,要为AutoCompleteTextView设置监听器实现补全自定

                    义的信息。

acv.setOnItemClickListener((AdapterView<?> parent, View view, int position, long id)->
        {
            Map<String, Object> mdata = (Map<String, Object>)mySimpleAdapter.getItem(position);
            Object s = mdata.get("文本介绍");
            acv.setText(s.toString());
        });

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值