AutoCompleteTextView输入框自动提示功能

      公司项目结束了,我们项目中有个需求,输入框中输入关键字,根据关键字自动提示相关的数据,看到这个需求,一下就想到了AutoCompleteTextView这个控件,以前做过简单的自动提示功能,但是这个需要自定义界面就需要重写适配器功能,期间遇到提示不出现等问题,把我最后的成果分享出来,希望对大家有帮助。

一、简单的自动提示功能

       输入框输入字符,根据字符简单的提示列表数据,但是提示列表的样式是一定的,比较单一。

	sugAdapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line , data);//data 提示的关联数据
        actDestination.setAdapter(sugAdapter);
        actDestination.setThreshold(1);

二、实现仿百度的提示列表

      提示列表的样式自定义,也可以在列表底部添加关闭按钮。
1、首先设置提示的开始字符数:actDestination.setThreshold(1);//默认是从第二个字符开始显示提示数据,这个根据需求自定义
2、自定义BaseAdapter ,设置自己需求需要的样式和功能,重点是必须实现Filterable接口,否则提示列表无法显示  。刚开始就没实现这个功能,设置适配器什么数据都无法关联提示出来,后来查资料发现还需要实现Filterable接口,否则会没有提示效果。
      
    @Override
    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new ListFilter();
        }
        return mFilter;
    }

    /**
     * 实现Filter 的两个方法:
     * 1.数据的过滤
     * 2.把过滤结果赋值给数据源
     */
    private class ListFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            FilterResults results = new FilterResults();
            //如果没有过滤条件则不过滤
            if (mBaiduData == null) {
                mBaiduData = new ArrayList(data);
            }
            //如果没有过滤条件则不过滤
            if (prefix == null || prefix.length() == 0) {
                results.values = mBaiduData;
                results.count = mBaiduData.size();
            } else {
                //过滤条件
                String prefixString = prefix.toString().toLowerCase();
                ArrayList unfilteredValues = mBaiduData;
                int count = unfilteredValues.size();
                ArrayList newValues = new ArrayList(count);
                //循环变量数据源,如果有属性满足过滤条件,则添加到result中
                for (int i = 0; i < count; i++) {
                    SuggestionInfo pc = unfilteredValues.get(i);
                    if (pc != null) {
                        if (pc.getKey().contains(prefixString)) {
                            newValues.add(pc);
                        }
                    }
                }

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

            return results;
        }

        //在这里返回过滤结果
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            data = (ArrayList) results.values;
            if (results.count > 0) {
                notifyDataSetChanged();//重绘当前可见区域
            } else {
                notifyDataSetInvalidated();//重绘控件,回复到初始状态
            }
        }
    }

三、附完整代码

    
public class SuggestPoiAdapter extends BaseAdapter implements Filterable {
    private static final int ITEM_BAIDU = 0;
    private static final int CLOSE_ITEM = 1;
    private Context mContext;
    private ArrayList data;
    private ArrayFilter mFilter;
    private ArrayList mBaiduData;
    private OnCloseListener onCloseListener;
    private OnItemClickListener onItemClickListener;


    public SuggestPoiAdapter(Context context, ArrayList suggestionInfos) {
        this.mContext = context;
        this.data = suggestionInfos;
    }

    public void setOnCloseListener(OnCloseListener onCloseListener) {
        this.onCloseListener = onCloseListener;
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    @Override
    public int getCount() {
        if (data == null) {
            return 0;
        } else if (data.size() > 6) {
            return 7;
        } else if (data.size() > 0) {
            return data.size() + 1;
        } else {
            return 0;
        }
    }

    @Override
    public Object getItem(int position) {
        return null;
    }


    @Override
    public int getItemViewType(int position) {
        int count;
        if (data.size() >= 6) {
            count = 6;
        } else {
            count = data.size();
        }
        if (position < count) {
            return ITEM_BAIDU;
        } else {
            return CLOSE_ITEM;  
        }
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        int itemViewType = getItemViewType(position);
        BaiDuViewHolder baiDuViewHolder = null;
        CloseViewHolder closeViewHolder = null;
        if (convertView == null) {
            switch (itemViewType) {
                case ITEM_BAIDU:
                    convertView = View.inflate(mContext, R.layout.item_baidu, null);
                    baiDuViewHolder = new BaiDuViewHolder();
                    baiDuViewHolder.baiduAdrr = (TextView) convertView.findViewById(R.id.tv_address); // 列表样式
                    convertView.setTag(baiDuViewHolder);
                    break;
                case CLOSE_ITEM:
                    convertView = View.inflate(mContext, R.layout.item_close, null);
                    closeViewHolder = new CloseViewHolder();
                    closeViewHolder.close = (TextView) convertView.findViewById(R.id.tv_close); // 关闭按钮
                    convertView.setTag(closeViewHolder);
                    break;
            }
        } else {
            switch (itemViewType) {
                case ITEM_BAIDU:
                    baiDuViewHolder = (BaiDuViewHolder) convertView.getTag();
                    break;
                case CLOSE_ITEM:
                    closeViewHolder = (CloseViewHolder) convertView.getTag();
                    break;
            }
        }

        switch (itemViewType) {
            case ITEM_BAIDU:
                String name = data.get(position).getKey();
                baiDuViewHolder.baiduAdrr.setText(name);
                baiDuViewHolder.baiduAdrr.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (onItemClickListener != null) {
                            onItemClickListener.onClickListener(position, data);
                        }
                    }
                });
                break;
            case CLOSE_ITEM:
                closeViewHolder.close.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (onCloseListener != null) {
                            onCloseListener.close();
                        }
                    }
                });
                break;
        }
        return convertView;
    }

    public void setData(ArrayList allPoi) {
        if (allPoi != null) {
            if (data != null) {
                data.clear();
            }
            data.addAll(allPoi);
        }
    }


    class BaiDuViewHolder {
        TextView baiduAdrr;
    }

    class CloseViewHolder {
        TextView close;
    }

    public interface OnCloseListener {
        void close();
    }

    public interface OnItemClickListener {
        void onClickListener(int position, ArrayList data);
    }

    @Override
    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new ArrayFilter();
        }
        return mFilter;
    }

    /**
     * 实现其中的两个方法,第一方法时数据的过滤逻辑,第二个方法是把过滤结果赋值给数据源。
     */
    private class ArrayFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            FilterResults results = new FilterResults();
            //如果没有过滤条件则不过滤
            if (mBaiduData == null) {
                mBaiduData = new ArrayList(data);
            }
            //如果没有过滤条件则不过滤
            if (prefix == null || prefix.length() == 0) {
                results.values = mBaiduData;
                results.count = mBaiduData.size();
            } else {
                //过滤条件
                String prefixString = prefix.toString().toLowerCase();
                ArrayList unfilteredValues = mBaiduData;
                int count = unfilteredValues.size();

                ArrayList newValues = new ArrayList(count);
                //循环变量数据源,如果有属性满足过滤条件,则添加到result中
                for (int i = 0; i < count; i++) {
                    SuggestionInfo pc = unfilteredValues.get(i);
                    if (pc != null) {
                        if (pc.getKey().contains(prefixString)) {
                            newValues.add(pc);
                        }
                    }
                }

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

            return results;
        }

        //在这里返回过滤结果
        @Override
        protected void publishResults(CharSequence constraint,
                                      FilterResults results) {
//          notifyDataSetInvalidated(),会重绘控件(还原到初始状态)
//          notifyDataSetChanged(),重绘当前可见区域
            //noinspection unchecked
            data = (ArrayList) results.values;
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    }

}




你可能感兴趣的:(AutoCompleteTextView输入框自动提示功能)