android 自动输入完成提示 自定义适配器适用于自定义分隔符带中文的提示

通过查看android 的ArrayAdapter这个类的源码,可以发现自动输入框所用的适配器的工作原理:适配器中有一个过滤器,每当输入一个字符时,该过滤器的performFiltering()被执行一次,用于查找给定的数组中前缀为输入字符串的项或者被空格分隔后的项的各个word的前缀为输入项的都加到最新提示列表,然后通知观察者更新提示列表。
明白了这个机制,可以很简单的根据需求进行改造。
例如 提示数组每一项的形式如 北京-BJ-BeiJing-1001,要求用‘-’ 分隔的项的每一个word都通过过滤器。
那么可以自己定义一个适配器 MyArrayAdapter ,通过copy ArrayAdapter的源码,只需改动下过滤器的过滤方法即可,下面只贴出关键代码,其他代码由于源码太长就不贴出了(都是ArrayAdapter
的源码)。只是对performFiltering(CharSequence prefix)方法作了下改变

 private class ArrayFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            FilterResults results = new FilterResults();

            if (mOriginalValues == null) {
                synchronized (mLock) {
                    mOriginalValues = new ArrayList<T>(mObjects);
                }
            }

            if (prefix == null || prefix.length() == 0) {
                ArrayList<T> list;
                synchronized (mLock) {
                    list = new ArrayList<T>(mOriginalValues);
                }
                results.values = list;
                results.count = list.size();
            } else {
                String prefixString = prefix.toString().toLowerCase(Locale.getDefault());

                ArrayList<T> values;
                synchronized (mLock) {
                    values = new ArrayList<T>(mOriginalValues);
                }

                final int count = values.size();
                final ArrayList<T> newValues = new ArrayList<T>();

                for (int i = 0; i < count; i++) {
                    final T value = values.get(i);
                    final String valueText = value.toString().toLowerCase(Locale.getDefault());
                    //Log.v("MyArrayAdapter",valueText);
                    // First match against the whole, non-splitted value
                    if (valueText.startsWith(prefixString)) {
                        newValues.add(value);
                    } else {
                        final String[] words = valueText.split("[-| ]");
                        // Start at index 0, in case valueText starts with space(s)
                        for (String w:words) {
                            //Log.v("MyArrayAdapter",words[k]);
                            if (w.startsWith(prefixString)) {
                                newValues.add(value);
                                break;
                            }
                        }
                    }
                }

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

            return results;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            //noinspection unchecked
            mObjects = (List<T>) results.values;
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    }

当然为了通用性,可以把分隔符参数化,在构造方法中传递过来。ArrayAdapter默认的分隔符是空格。

通过上述自定义的改造,例如字符串 bj-1024-北京 王五|代收 将被分隔成bj、1024、北京、王五、代收 5个字段,可以用于匹配自动输入完成文本框。

autoCompleteTextView.setAdapter(new MyArrayAdapter<>(this,
                                R.layout.spinner_simple_item, list));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值