您当前的位置: 首页 >  android

命运之手

暂无认证

  • 2浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【Android】【自定义控件】自动填充输入框,自定义AutoCompleteTextView

命运之手 发布时间:2019-07-12 17:58:58 ,浏览量:2

android自带的AutoCompleteTextView,可以简单地实现自动补全功能,但是限制较多 这里介绍如何通过自定义来扩展AutoCompleteTextView功能,包括以下功能

  • 解决最小字符匹配数量限制,零个字符时也可提示全部选项
  • 自定义匹配规则,可以自己通过代码实现拼音匹配,模糊匹配等功能
  • 集成Adapter,不用再创建Adapter,直接传入一个选项数组即可

AutoCompleteEdit


//自动补全输入框
public class AutoCompleteEdit extends AppCompatAutoCompleteTextView {

    private int threshold = 0;

    private FilterableTextAdapter adapter;

    public AutoCompleteEdit(Context context) {
        super(context);
        init();
    }

    public AutoCompleteEdit(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public AutoCompleteEdit(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {

        //下拉项适配器
        adapter = new FilterableTextAdapter();
        adapter.autoCompleteEdit = this;
        setAdapter(adapter);

        //文字改变时,更新建议项
        addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                adapter.getFilter().filter(s);
            }
        });

        //获得焦点时,更新建议项
        setOnFocusChangeListener((v, hasFocus) -> {
            if (hasFocus)
                showDropDown();
        });

        //有焦点重新点击时,也更新建议项
        setOnClickListener(v -> {
            if (getText().toString().isEmpty())
                showDropDown();
        });
    }

    @Override
    public boolean enoughToFilter() {
        return getText().length() >= threshold;
    }

    //设置字符匹配数量
    public AutoCompleteEdit threshold(int threshold) {
        this.threshold = threshold;
        return this;
    }

    //更新全部可选数据
    public AutoCompleteEdit reset(List datas) {
        adapter.reset(datas);
        return this;
    }

    //下拉选项更新时,执行回调
    public AutoCompleteEdit onFilter(FilterableTextAdapter.OnFilter onFilter) {
        adapter.onFilter((items, count) -> {
            setDropDownHeight(600);
            showDropDown();
        });
        return this;
    }

}

FilterableTextAdapter


//带数据过滤功能的TextAdapter
public class FilterableTextAdapter extends BaseAdapter implements Filterable {

    protected AutoCompleteEdit autoCompleteEdit;

    private List originItems = new ArrayList();
    private List filteredItems = new ArrayList();

    private TextFilter filter = new TextFilter();

    private OnFilter onFilter;

    public void onFilter(OnFilter onFilter) {
        this.onFilter = onFilter;
    }

    public int getCount() {
        return filteredItems.size();
    }

    @Override
    public String getItem(int position) {
        return filteredItems.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View root = ViewManager.inflate(parent.getContext(), R.layout.item_text_list);
        TextView text = root.findViewById(R.id.tv);
        text.setText(getItem(position));
        //点击设置文本,并关闭下拉框
        root.setOnClickListener(v -> {
            autoCompleteEdit.setText(text.getText());
            autoCompleteEdit.setSelection(text.getText().length());
            autoCompleteEdit.dismissDropDown();
        });
        return root;
    }

    @Override
    public Filter getFilter() {
        return filter;
    }

    //重置全部可选数据
    public void reset(List items) {
        originItems.clear();
        originItems.addAll(items);
    }

    //文本过滤器,用于定义匹配规则,更新匹配项
    public class TextFilter extends Filter {

        //数据过滤
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            String key = constraint.toString().toLowerCase();
            List temp = new ArrayList();
            //如果没有限制,则显示全部
            if (constraint.toString().isEmpty()) {
                temp.addAll(originItems);
                FilterResults results = new FilterResults();
                results.values = temp;
                results.count = temp.size();
                return results;
            }
            //如果不是拼音,以关键字开头,或包含关键字,则匹配
            for (String item : originItems) {
                if (item.toLowerCase().startsWith(key))
                    temp.add(item);
            }
            for (String item : originItems) {
                if (item.toLowerCase().contains(key) && !temp.contains(item))
                    temp.add(item);
            }
            //如果是拼音,拼音以关键字开头,或简拼以关键字开头,则匹配
            if (key.matches("^[a-z]+$")) {
                for (String item : originItems) {
                    if (TextUtil.getSimplePinyin(item).startsWith(key) && !temp.contains(item))
                        temp.add(item);
                }
                for (String item : originItems) {
                    if (TextUtil.getPinyin(item).contains(key) && !temp.contains(item))
                        temp.add(item);
                }
            }
            //封装过滤结果
            FilterResults results = new FilterResults();
            results.values = temp;
            results.count = temp.size();
            return results;
        }

        //发布过滤结果
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            //根据过滤结果去更新adapter
            if (results.count == 0)
                notifyDataSetInvalidated();
            else {
                filteredItems = (List) results.values;
                notifyDataSetChanged();
            }
            //执行回调
            if (onFilter != null)
                onFilter.OnFilter((List) results.values, results.count);
        }
    }

    public interface OnFilter {

        void OnFilter(List items, int count);
    }

}

LoginActivity


public class LoginActivity extends CommonActivity {

    @BindView(R.id.edit)
    AutoCompleteEdit edit;

    protected void create() {
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this, ctx);
        init();
    }

    private void init() {
        List datas = new LinkedList();
        datas.add("ABC");
        datas.add("abc");
        datas.add("中国人");
        datas.add("abc中国人");
        datas.add("中国人abc");
        edit.reset(datas);
    }

}

上面部分功能用到了工具类,需要自己修改,但是核心代码全部齐备,可以轻松修改

运行效果 在这里插入图片描述

关注
打赏
1654938663
查看更多评论
立即登录/注册

微信扫码登录

0.0408s