AutoCompleteTextView 文本过滤
AutoCompleteTextView Text Filtering
我正在尝试使用 AutoCompleteTextView
进行过滤,但我遇到了过滤器问题。它 returns ArrayList
中的所有项目而不是过滤的项目。下面是我的代码:
Filter nameFilter = new Filter() {
@Override
public String convertResultToString(Object resultValue) {
String str = ((State)(resultValue)).getName();
Log.e("Conv"+TAG, str);
return str;
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
if(constraint != null) {
suggestions.clear();
for (State customer : itemsAll) {
Log.e("Ite "+TAG, "" + itemsAll.size());
Log.e("Cons " + TAG, constraint.toString());
Log.e("Sta" + TAG, customer.getName()); //This is always null
if(customer.getName().toLowerCase().contains(constraint.toString().toLowerCase())) {
suggestions.add(customer);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = suggestions;
filterResults.count = suggestions.size();
return filterResults;
} else {
return new FilterResults();
}
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
List<State> filteredList = (ArrayList<State>) results.values;
if(results != null && results.count > 0) {
clear();
Log.e("D "+TAG, ""+results.count);
for (State c : filteredList) {
Log.e("The "+TAG, c.getName() + " " + c.getId());
add(c);
notifyDataSetChanged();
}
} else {
Log.e(TAG, "Empty Filter");
notifyDataSetChanged();
}
}
};
然后我开始四处登录,我注意到这一行始终为空 Log.e("Sta" + TAG, customer.getName()); //This is always null
而这一行 Log.e("Cons " + TAG, constraint.toString());
和这一行 Log.e("Ite "+TAG, "" + itemsAll.size());
永远不会为空。除非没有传递文本,否则约束肯定不能为 null。但是,当 itemsAll.size()
不为 null 或为空时,第一个对象为 null。我很迷惑。下面是我的 List
初始化
private static final String TAG = "StateAdapter";
private ArrayList<State> items;
private ArrayList<State> itemsAll;
private ArrayList<State> suggestions;
private Context context;
private int viewResourceId;
public StateAutoCompleteAdapter(Context context, int resource, int textViewResourceId, ArrayList<State> objects) {
super(context, resource, textViewResourceId, objects);
this.context = context;
this.items = objects;
this.itemsAll = new ArrayList<State>(items);
this.suggestions = new ArrayList<State>();
this.viewResourceId = resource;
}
并且对于 getView
函数
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(viewResourceId, null);
}
State customer = items.get(position);
if (customer != null) {
TextView customerNameLabel = (TextView) v.findViewById(R.id.bakerName);
TextView bakerAddress = (TextView) v.findViewById(R.id.bakerAddress);
if (customerNameLabel != null) {
// Log.i(MY_DEBUG_TAG, "getView Customer Name:"+customer.getName());
customerNameLabel.setText(customer.getName());
bakerAddress.setVisibility(View.GONE);
}
}
return v;
}
clear() 方法可能会导致问题。所以请检查它的代码,你正在清理哪个数组列表。
另一个问题是因为您在 getView()
中使用 State customer = items.get(position);
并在 performFiltering(CharSequence constraint)
中使用 suggestions.add(customer);
希望对您有所帮助。
所以,我自己解决了这个问题。所以,我使用普通的 BaseAdapter
并扩展 Filterable
所以,对于那些可能需要如何将 RealmDB
与 AutoCompleteTextView
一起使用的人,你去
public class LgasAutoCompleteAdapter extends BaseAdapter implements Filterable {
private static final String TAG = "LgasAutoComp";
private Context mContext;
private List<Lga> mResult = new ArrayList<>();
private LayoutInflater inflater;
public LgasAutoCompleteAdapter(Context mContext) {
this.mContext = mContext;
}
@Override
public int getCount() {
return mResult.size();
}
@Override
public Object getItem(int position) {
return mResult.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (view == null)
view = inflater.inflate(R.layout.item_baker_autocomplete, parent, false);
Lga lga = mResult.get(position);
TextView customerNameLabel = (TextView) view.findViewById(R.id.bakerName);
TextView bakerAddress = (TextView) view.findViewById(R.id.bakerAddress);
if (lga != null) {
if (customerNameLabel != null) {
// Log.i(MY_DEBUG_TAG, "getView Customer Name:"+customer.getName());
customerNameLabel.setText(lga.getName());
bakerAddress.setVisibility(View.GONE);
}
}
return view;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
return null;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults filterResults) {
if (constraint != null) {
//String query = constraint.toString().toLowerCase();
mResult = filterStates(constraint.toString());
Log.e(TAG, ""+mResult.size());
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
}
@NonNull
private List<Lga> filterStates(String query) {
Realm mRealm = RealmUtils.getRealmInstance(mContext);
return mRealm.where(Lga.class)
.contains("name", query)
.or()
.beginsWith("name", query)
.findAll();
}
}
我正在尝试使用 AutoCompleteTextView
进行过滤,但我遇到了过滤器问题。它 returns ArrayList
中的所有项目而不是过滤的项目。下面是我的代码:
Filter nameFilter = new Filter() {
@Override
public String convertResultToString(Object resultValue) {
String str = ((State)(resultValue)).getName();
Log.e("Conv"+TAG, str);
return str;
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
if(constraint != null) {
suggestions.clear();
for (State customer : itemsAll) {
Log.e("Ite "+TAG, "" + itemsAll.size());
Log.e("Cons " + TAG, constraint.toString());
Log.e("Sta" + TAG, customer.getName()); //This is always null
if(customer.getName().toLowerCase().contains(constraint.toString().toLowerCase())) {
suggestions.add(customer);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = suggestions;
filterResults.count = suggestions.size();
return filterResults;
} else {
return new FilterResults();
}
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
List<State> filteredList = (ArrayList<State>) results.values;
if(results != null && results.count > 0) {
clear();
Log.e("D "+TAG, ""+results.count);
for (State c : filteredList) {
Log.e("The "+TAG, c.getName() + " " + c.getId());
add(c);
notifyDataSetChanged();
}
} else {
Log.e(TAG, "Empty Filter");
notifyDataSetChanged();
}
}
};
然后我开始四处登录,我注意到这一行始终为空 Log.e("Sta" + TAG, customer.getName()); //This is always null
而这一行 Log.e("Cons " + TAG, constraint.toString());
和这一行 Log.e("Ite "+TAG, "" + itemsAll.size());
永远不会为空。除非没有传递文本,否则约束肯定不能为 null。但是,当 itemsAll.size()
不为 null 或为空时,第一个对象为 null。我很迷惑。下面是我的 List
初始化
private static final String TAG = "StateAdapter";
private ArrayList<State> items;
private ArrayList<State> itemsAll;
private ArrayList<State> suggestions;
private Context context;
private int viewResourceId;
public StateAutoCompleteAdapter(Context context, int resource, int textViewResourceId, ArrayList<State> objects) {
super(context, resource, textViewResourceId, objects);
this.context = context;
this.items = objects;
this.itemsAll = new ArrayList<State>(items);
this.suggestions = new ArrayList<State>();
this.viewResourceId = resource;
}
并且对于 getView
函数
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(viewResourceId, null);
}
State customer = items.get(position);
if (customer != null) {
TextView customerNameLabel = (TextView) v.findViewById(R.id.bakerName);
TextView bakerAddress = (TextView) v.findViewById(R.id.bakerAddress);
if (customerNameLabel != null) {
// Log.i(MY_DEBUG_TAG, "getView Customer Name:"+customer.getName());
customerNameLabel.setText(customer.getName());
bakerAddress.setVisibility(View.GONE);
}
}
return v;
}
clear() 方法可能会导致问题。所以请检查它的代码,你正在清理哪个数组列表。
另一个问题是因为您在 getView()
中使用 State customer = items.get(position);
并在 performFiltering(CharSequence constraint)
suggestions.add(customer);
希望对您有所帮助。
所以,我自己解决了这个问题。所以,我使用普通的 BaseAdapter
并扩展 Filterable
所以,对于那些可能需要如何将 RealmDB
与 AutoCompleteTextView
一起使用的人,你去
public class LgasAutoCompleteAdapter extends BaseAdapter implements Filterable {
private static final String TAG = "LgasAutoComp";
private Context mContext;
private List<Lga> mResult = new ArrayList<>();
private LayoutInflater inflater;
public LgasAutoCompleteAdapter(Context mContext) {
this.mContext = mContext;
}
@Override
public int getCount() {
return mResult.size();
}
@Override
public Object getItem(int position) {
return mResult.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (view == null)
view = inflater.inflate(R.layout.item_baker_autocomplete, parent, false);
Lga lga = mResult.get(position);
TextView customerNameLabel = (TextView) view.findViewById(R.id.bakerName);
TextView bakerAddress = (TextView) view.findViewById(R.id.bakerAddress);
if (lga != null) {
if (customerNameLabel != null) {
// Log.i(MY_DEBUG_TAG, "getView Customer Name:"+customer.getName());
customerNameLabel.setText(lga.getName());
bakerAddress.setVisibility(View.GONE);
}
}
return view;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
return null;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults filterResults) {
if (constraint != null) {
//String query = constraint.toString().toLowerCase();
mResult = filterStates(constraint.toString());
Log.e(TAG, ""+mResult.size());
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
}
@NonNull
private List<Lga> filterStates(String query) {
Realm mRealm = RealmUtils.getRealmInstance(mContext);
return mRealm.where(Lga.class)
.contains("name", query)
.or()
.beginsWith("name", query)
.findAll();
}
}