您的位置:首页 > 其它

AutoCompleteTextView输入框自动提示功能

2017-08-03 14:56 405 查看

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

一、简单的自动提示功能

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

sugAdapter = new ArrayAdapter<String>(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<SuggestionInfo>(data);
}
//如果没有过滤条件则不过滤
if (prefix == null || prefix.length() == 0) {
results.values = mBaiduData;
results.count = mBaiduData.size();
} else {
//过滤条件
String prefixString = prefix.toString().toLowerCase();
ArrayList<SuggestionInfo> unfilteredValues = mBaiduData;
int count = unfilteredValues.size();
ArrayList<SuggestionInfo> newValues = new ArrayList<SuggestionInfo>(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<SuggestionInfo>) 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<SuggestionInfo> data;
private ArrayFilter mFilter;
private ArrayList<SuggestionInfo> mBaiduData;
private OnCloseListener onCloseListener;
private OnItemClickListener onItemClickListener;

public SuggestPoiAdapter(Context context, ArrayList<SuggestionInfo> 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 (positio
ac3a
n < 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<SuggestionInfo> 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<SuggestionInfo> 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<SuggestionInfo>(data);
}
//如果没有过滤条件则不过滤
if (prefix == null || prefix.length() == 0) {
results.values = mBaiduData;
results.count = mBaiduData.size();
} else {
//过滤条件
String prefixString = prefix.toString().toLowerCase();
ArrayList<SuggestionInfo> unfilteredValues = mBaiduData;
int count = unfilteredValues.size();

ArrayList<SuggestionInfo> newValues = new ArrayList<SuggestionInfo>(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<SuggestionInfo>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: