Android ListView未使用过滤器进行更新

时间:2017-12-20 19:35:10

标签: java android

我有一个列表视图,我尝试根据用户点击的按钮进行过滤。

过滤器正在运行,我在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();
            }
        }
    }
}

1 个答案:

答案 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();
}