我有一个列表视图,我尝试根据用户点击的按钮进行过滤。
过滤器正在运行,我在publishResults方法中得到了我期望的结果,但该列表永远不会更新。我已经有了notifyDataSetChanged(),但这似乎没有做任何事情。
最低SDK级别21并编译26。
mAdapter = new QuakeAdapter(this, new ArrayList<QuakeItem>());
ListView earthquakeListView = (ListView) findViewById(R.id.list);
earthquakeListView.setAdapter(mAdapter);
设置过滤器
public void filterList(View view){
mAdapter.resetData();
Log.d(LOG_TAG, "FILTER Tsunami" + mAdapter.quakeList);
mAdapter.getFilter().filter("tsunamiOnly");
}
public void filterListEarthquake(View view){
mAdapter.resetData();
Log.d(LOG_TAG, "FILTER earthquake" + mAdapter.quakeList);
mAdapter.getFilter().filter("earthquakeOnly");
}
自定义适配器
public class QuakeAdapter extends ArrayAdapter<QuakeItem> implements Filterable {
public ArrayList<QuakeItem> origQuakeList;
public ArrayList<QuakeItem> quakeList;
private Filter quakeFilter;
private Context mContext;
public static final String LOG_TAG = QuakeAdapter.class.getName();
public QuakeAdapter(Activity context, ArrayList<QuakeItem> quakeItems){
super(context, 0, quakeItems);
origQuakeList = quakeItems;
quakeList = quakeItems;
mContext = context;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent){
View listItemView = convertView;
if(listItemView == null){
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false
);
}
QuakeItem currentItem = getItem(position);
double mag = currentItem.getMagnitude();
TextView magnitudeTextView = (TextView) listItemView.findViewById(R.id.magnitudeView);
magnitudeTextView.setText(formatMagnitude(mag));
GradientDrawable magnitudeCircle = (GradientDrawable) magnitudeTextView.getBackground();
int magnitudeColour = getMagnitudeColour(mag);
magnitudeCircle.setColor(magnitudeColour);
int isTsunami = currentItem.getTsunami();
int strokeColor = magnitudeColour;
if (isTsunami==1){
strokeColor = Color.BLACK;
}
magnitudeCircle.setStroke(6, strokeColor);
String[] formattedString = formatLocation(currentItem.getLocation());
TextView locationOffsetTextView = (TextView) listItemView.findViewById(R.id.locationOffsetView);
locationOffsetTextView.setText(formattedString[0]);
TextView locationTextView = (TextView) listItemView.findViewById(R.id.locationView);
locationTextView.setText(formattedString[1]);
Long timeInMilliseconds = currentItem.getTime();
TextView timeTextView = (TextView) listItemView.findViewById(R.id.timeView);
timeTextView.setText(formatTime(timeInMilliseconds));
TextView dateTextView = (TextView) listItemView.findViewById(R.id.dateView);
dateTextView.setText(formatDate(timeInMilliseconds));
return listItemView;
}
public void resetData() {
quakeList = origQuakeList;
}
@Override
public Filter getFilter() {
if (quakeFilter == null)
quakeFilter = new QuakeFilter();
return quakeFilter;
}
private class QuakeFilter extends Filter{
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint == null || constraint.length() == 0){
// No filter found, return original list
results.values = origQuakeList;
results.count = origQuakeList.size();
} else {
// Perform filter
ArrayList<QuakeItem> nQuakeList = new ArrayList<QuakeItem>();
switch (constraint.toString()){
case "tsunamiOnly":
for (QuakeItem q : quakeList){
if (q.getTsunami() == 1){
nQuakeList.add(q);
}
}
break;
case "earthquakeOnly":
for (QuakeItem q : quakeList){
if (q.getTsunami() == 0){
nQuakeList.add(q);
}
}
break;
}
results.values = nQuakeList;
results.count = nQuakeList.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults filterResults) {
if (filterResults.count == 0){
notifyDataSetInvalidated();
} else {
quakeList = (ArrayList<QuakeItem>) filterResults.values;
Log.d(LOG_TAG, "FILTER " + quakeList);
notifyDataSetChanged();
}
}
}
}
答案 0 :(得分:0)
解决了我自己的问题。正如所料,这是一件愚蠢的事。
我在我的适配器中缺少getCount,getItem和getItemId。
public int getCount() {
return quakeList.size();
}
public QuakeItem getItem(int position) {
return quakeList.get(position);
}
public long getItemId(int position) {
return quakeList.get(position).hashCode();
}