使用 EditText 过滤 ListView
Filter ListView with EditText
我正在尝试用 EditText
中的文本过滤 ListView
,但我根本没有得到任何过滤器。
我正在关注这个答案:Answer。
我的适配器 class 扩展了 BaseAdapter
并实现了 Filterable
,它看起来像这样:
public class ListBaseAdapter extends BaseAdapter implements Filterable {
Context context;
ArrayList<Bean> bean;
ArrayList<Bean> beanFiltered;
Typeface fonts1, fonts2;
public ListBaseAdapter(Context context, ArrayList<Bean> bean) {
this.context = context;
this.bean = bean;
this.beanFiltered = bean;
}
@Override
public int getCount() {
return bean.size();
}
@Override
public Object getItem(int position) {
return bean.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
fonts1 = Typeface.createFromAsset(context.getAssets(),
"fonts/Lato-Light.ttf");
fonts2 = Typeface.createFromAsset(context.getAssets(),
"fonts/Lato-Regular.ttf");
ViewHolder viewHolder = null;
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list, null);
viewHolder = new ViewHolder();
viewHolder.newsimage1 = convertView.findViewById(R.id.newsimage1);
viewHolder.newsimage2 = convertView.findViewById(R.id.newsimage2);
viewHolder.more = convertView.findViewById(R.id.more);
viewHolder.newsname = convertView.findViewById(R.id.newsname);
viewHolder.time = convertView.findViewById(R.id.time);
viewHolder.news = convertView.findViewById(R.id.news);
viewHolder.newssub = convertView.findViewById(R.id.newssub);
viewHolder.intrest = convertView.findViewById(R.id.intrest);
viewHolder.newsname.setTypeface(fonts1);
viewHolder.time.setTypeface(fonts1);
viewHolder.news.setTypeface(fonts2);
viewHolder.newssub.setTypeface(fonts1);
viewHolder.intrest.setTypeface(fonts1);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final Bean bean = (Bean) getItem(position);
viewHolder.newsimage1.setImageResource(bean.getNewsimage1());
viewHolder.newsimage2.setImageResource(bean.getNewsimage2());
viewHolder.more.setImageResource(bean.getMore());
viewHolder.newsname.setText(bean.getNewsname());
viewHolder.time.setText(bean.getTime());
viewHolder.news.setText(bean.getNews());
viewHolder.newssub.setText(bean.getNewssub());
viewHolder.intrest.setText(bean.getIntrest());
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context, ItemDetailActivity.class);
intent.putExtra("text", bean.getNewssub());
context.startActivity(intent);
}
});
return convertView;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
//no constraint given, just return all the data. (no search)
results.count = bean.size();
results.values = bean;
} else {//do the search
List<Bean> resultsData = new ArrayList<>();
String searchStr = constraint.toString();
for (Bean o : bean)
if (o.getNews().startsWith(searchStr)) resultsData.add(o);
results.count = resultsData.size();
results.values = resultsData;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
beanFiltered = (ArrayList<Bean>) results.values;
notifyDataSetChanged();
}
};
}
private class ViewHolder {
ImageView newsimage1;
ImageView newsimage2;
ImageView more;
TextView newsname;
TextView time;
TextView news;
TextView newssub;
TextView intrest;
}
}
然后在我的 activity, :
searchParam.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
baseAdapter.getFilter().filter(charSequence);
}
@Override
public void afterTextChanged(Editable editable) {
}
});
但我仍然没有得到任何过滤结果。我做错了什么
您的列表基于 bean 而不是 beanFiltered。这就是 notifyDataSetChanged 不起作用的原因。 getCount() 和 getItem(int position) 始终在 bean 上工作。这就是过滤器不起作用的原因。请按以下更改:
@Override
public int getCount() {
return beanFiltered.size();
}
@Override
public Object getItem(int position) {
return beanFiltered.get(position);
}
我正在尝试用 EditText
中的文本过滤 ListView
,但我根本没有得到任何过滤器。
我正在关注这个答案:Answer。
我的适配器 class 扩展了 BaseAdapter
并实现了 Filterable
,它看起来像这样:
public class ListBaseAdapter extends BaseAdapter implements Filterable {
Context context;
ArrayList<Bean> bean;
ArrayList<Bean> beanFiltered;
Typeface fonts1, fonts2;
public ListBaseAdapter(Context context, ArrayList<Bean> bean) {
this.context = context;
this.bean = bean;
this.beanFiltered = bean;
}
@Override
public int getCount() {
return bean.size();
}
@Override
public Object getItem(int position) {
return bean.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
fonts1 = Typeface.createFromAsset(context.getAssets(),
"fonts/Lato-Light.ttf");
fonts2 = Typeface.createFromAsset(context.getAssets(),
"fonts/Lato-Regular.ttf");
ViewHolder viewHolder = null;
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.list, null);
viewHolder = new ViewHolder();
viewHolder.newsimage1 = convertView.findViewById(R.id.newsimage1);
viewHolder.newsimage2 = convertView.findViewById(R.id.newsimage2);
viewHolder.more = convertView.findViewById(R.id.more);
viewHolder.newsname = convertView.findViewById(R.id.newsname);
viewHolder.time = convertView.findViewById(R.id.time);
viewHolder.news = convertView.findViewById(R.id.news);
viewHolder.newssub = convertView.findViewById(R.id.newssub);
viewHolder.intrest = convertView.findViewById(R.id.intrest);
viewHolder.newsname.setTypeface(fonts1);
viewHolder.time.setTypeface(fonts1);
viewHolder.news.setTypeface(fonts2);
viewHolder.newssub.setTypeface(fonts1);
viewHolder.intrest.setTypeface(fonts1);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final Bean bean = (Bean) getItem(position);
viewHolder.newsimage1.setImageResource(bean.getNewsimage1());
viewHolder.newsimage2.setImageResource(bean.getNewsimage2());
viewHolder.more.setImageResource(bean.getMore());
viewHolder.newsname.setText(bean.getNewsname());
viewHolder.time.setText(bean.getTime());
viewHolder.news.setText(bean.getNews());
viewHolder.newssub.setText(bean.getNewssub());
viewHolder.intrest.setText(bean.getIntrest());
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context, ItemDetailActivity.class);
intent.putExtra("text", bean.getNewssub());
context.startActivity(intent);
}
});
return convertView;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0) {
//no constraint given, just return all the data. (no search)
results.count = bean.size();
results.values = bean;
} else {//do the search
List<Bean> resultsData = new ArrayList<>();
String searchStr = constraint.toString();
for (Bean o : bean)
if (o.getNews().startsWith(searchStr)) resultsData.add(o);
results.count = resultsData.size();
results.values = resultsData;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
beanFiltered = (ArrayList<Bean>) results.values;
notifyDataSetChanged();
}
};
}
private class ViewHolder {
ImageView newsimage1;
ImageView newsimage2;
ImageView more;
TextView newsname;
TextView time;
TextView news;
TextView newssub;
TextView intrest;
}
}
然后在我的 activity, :
searchParam.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
baseAdapter.getFilter().filter(charSequence);
}
@Override
public void afterTextChanged(Editable editable) {
}
});
但我仍然没有得到任何过滤结果。我做错了什么
您的列表基于 bean 而不是 beanFiltered。这就是 notifyDataSetChanged 不起作用的原因。 getCount() 和 getItem(int position) 始终在 bean 上工作。这就是过滤器不起作用的原因。请按以下更改:
@Override
public int getCount() {
return beanFiltered.size();
}
@Override
public Object getItem(int position) {
return beanFiltered.get(position);
}