首先,本文灵感和主要代码来源于自定义autoCompleteTextView实现自己的匹配规则。有兴趣的朋友可以自己去看看,写这篇文章的原因一个是为了记录,因为上述说的文章中对于使用,没有过多介绍,以及代码有一些问题(先把问题说了吧,如果照着上文中的适配器去复制实现,最后效果是可以达到,但是一旦点击,autoCompleteTextview就会显示乱码,而不是你所选择的值,如下图)。
这是因为上述文章中的代码没有写过滤器的返回结果
//在自定义的过滤器MyFilter中加入以下代码就好,具体要返回什么你可以自己在实体类里写好get就行
@Override
public CharSequence convertResultToString(Object resultValue) {
T list = (T) resultValue;
return list.getValue();
}
于是乎我通过研究和实践,解决了输入姓名或者姓名对应的其他参数同样能在列表中显示姓名。(需求就是能够通过姓名或编号查询,但又只显示姓名)
首先上述文章中的代码是通用代码,可以直接复制到自己的项目工程中,使用起来也十分的方便,首先去掉最外面的类的< T >,然后替换掉类里面所有的< T >,换成自己的实体类。就可以使用了。文中没有提到的控件填充和绑定比较简单如下。
AutoCompleteTextView act;
act = findViewbyId(R.id.act);
private testAdapter adapter;
//自己分析一下构造函数就行,我这里传进去的list只有两个有效参数就是姓名和编号
adapter = new testAdapter(MyApplication.getContext(),android.R.layout.simple_dropdown_item_1line,MainActivity.userList);
act.setAdapter(adapter);
然后就是自定义匹配规则部分,是修改原文中的这一部分,实际上就是for循环匹配,constraint就是正在输入的字符串。
//原文
for(int i = 0;i < count;i++)
{
T value = mOriginalValues.get(i);
String valueText = value.toString();
//自定义匹配规则
if(valueText != null && constraint != null && valueText.contains(constraint))
{
values.add(value);
}
}
为了能够多对一的匹配我将它改成了以下,非常的简单就实现了多对一的匹配
//多对一
for(int i = 0;i < count;i++)
{
T value = mOriginalValues.get(i);
String ClerkName = value.getClerkName();
String ClerkNumber = value.getClerkNumber();
//自定义匹配规则
if(value != null && constraint != null && ClerkName != null && ClerkNumber != null)
{
if (ClerkName.contains(constraint) || ClerkNumber.contains(constraint))
values.add(value);
}
}
保存原文源码防止走失:
public class myAdapter<T> extends BaseAdapter implements Filterable
{
private List<T> mOriginalValues;
private List<T> mObject;
private final Object mLock = new Object();
private int mResouce;
private MyFilter myFilter = null;
private LayoutInflater inflater;
public myAdapter(Context context,int TextViewResouceId,List<T> objects)
{
init(context,TextViewResouceId,objects);
}
private void init(Context context, int textViewResouceId, List<T> objects)
{
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mObject = objects;
mResouce = textViewResouceId;
myFilter = new MyFilter();
}
@Override
public int getCount() {
return mObject.size();
}
@Override
public T getItem(int position) {
return mObject.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getViewFromResouce(position,convertView,parent,mResouce);
}
private View getViewFromResouce(int position, View convertView,
ViewGroup parent, int mResouce2) {
if(convertView == null)
{
convertView = inflater.inflate(mResouce2, parent,false);
}
TextView tv = (TextView)convertView;
T item = getItem(position);
if(item instanceof CharSequence)
{
tv.setText((CharSequence)item);
}
else
{
tv.setText(item.toString());
}
return tv;
}
//返回过滤器
@Override
public Filter getFilter() {
return myFilter;
}
//自定义过滤器
private class MyFilter extends Filter
{
//得到过滤结果
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(mOriginalValues == null)
{
synchronized (mLock) {
mOriginalValues = new ArrayList<T>(mObject);
}
}
int count = mOriginalValues.size();
ArrayList<T> values = new ArrayList<T>();
for(int i = 0;i < count;i++)
{
T value = mOriginalValues.get(i);
String valueText = value.toString();
//自定义匹配规则
if(valueText != null && constraint != null && valueText.contains(constraint))
{
values.add(value);
}
}
results.values = values;
results.count = values.size();
return results;
}
//发布过滤结果
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
//把搜索结果赋值给mObject这样每次输入字符串的时候就不必
//从所有的字符串中查找,从而提高了效率
mObject = (List<T>)results.values;
if(results.count > 0)
{
notifyDataSetChanged();
}
else
{
notifyDataSetInvalidated();
}
}
//返回选中结果
@Override
public CharSequence convertResultToString(Object resultValue) {
T list = (T) resultValue;
return list.getClerkName();
}
}
}