简体   繁体   English

Android ListView不使用过滤器更新

[英]Android ListView not updating with filter

I've got a list view that I'm trying to filter depending on which button the user clicks. 我有一个列表视图,我试图根据用户单击哪个按钮进行过滤。

The filter is working, I'm getting the results I expect inside the publishResults method but the list is then never updating. 过滤器正在运行,我在publishResults方法中获得了期望的结果,但是列表从未更新。 I've got notifyDataSetChanged() but this doesn't seem to do anything. 我有notifyDataSetChanged(),但这似乎什么也没做。

Min SDK level 21 and compiled 26. 最低SDK级别21,已编译26。

    mAdapter = new QuakeAdapter(this, new ArrayList<QuakeItem>());
    ListView earthquakeListView = (ListView) findViewById(R.id.list);
    earthquakeListView.setAdapter(mAdapter);

Setting the filter 设置过滤器

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");
}

Custom Adapter 定制适配器

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

Solved my own problem. 解决了我自己的问题。 As expected it was something stupid. 不出所料,这有点愚蠢。

I was missing getCount, getItem and getItemId in my adapter. 我在适配器中缺少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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM