Filter list not reappearing after empty view shown

不想你离开。 提交于 2020-01-03 05:57:36

问题


For some reason after being shown an empty view for no matching items, my list view won't reappear after removing all text from the search view.

Within my adapter class, AFAIK .clear() in mData.clear(); needs to change to something else but I don't know what to.

ItemListAdapter class

public class ItemListAdapter extends BaseAdapter implements Filterable {

    private List<Victoria> mData;
    private List<Victoria> mFilteredData;
    private LayoutInflater mInflater;
    private ItemFilter mFilter;

    public ItemListAdapter (List<Victoria> data, Context context) {
        mData = data;
        mFilteredData = new ArrayList(mData);
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return mFilteredData.size();
    }

    @Override
    public String getItem(int position) {
        return mFilteredData.get(position).getItem();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;
        if (convertView == null) {
           convertView = mInflater.inflate(R.layout.item_row, parent, false);
            holder = new ViewHolder();

            holder.title = (TextView) convertView.findViewById(R.id.item_title);
            holder.description = (TextView) convertView.findViewById(R.id.item_description);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.title.setText(mFilteredData.get(position).getItem());
        holder.description.setText(mFilteredData.get(position).getItemDescription());

        return convertView;
    }

    @Override
    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new ItemFilter();
        }
        return mFilter;
    }

    /**
     * View holder
     */
    static class ViewHolder {
        private TextView title;
        private TextView description;
    }

    /**
     * Filter for filtering list items
     */
    /**
     * <p>An array filter constrains the content of the array adapter with
     * a prefix. Each item that does not start with the supplied prefix
     * is removed from the list.</p>
     */
    private class ItemFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();

            if (TextUtils.isEmpty(constraint)) {
                results.count = mData.size();
                results.values = mData;
            } else {
                //Create a new list to filter on
                List<Victoria> resultList = new ArrayList<Victoria>();
                for (Victoria str : mData) {
                    if (str.getItemDescription().toLowerCase().contains(constraint.toString().toLowerCase())) {
                        resultList.add(str);
                    }
                }
                results.count = resultList.size();
                results.values = resultList;
            }
            return results;
        }

        /**
         * Runs on ui thread
         * @param constraint the constraint used for the result
         * @param results the results to display
         */
        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results.count == 0) {
                //Make list invisible
                //Make text view visible
                mFilteredData.clear();
                notifyDataSetInvalidated();
            } else {
                mFilteredData = (ArrayList<Victoria>)results.values;
                notifyDataSetChanged();
            }
        }
    }
}

Before filtering

After filtering with an invalid character

After clearing search view and trying to show list again


回答1:


Couple small fixes should get things working right for you. First, mData and mFilteredData data should be two different instances at all times. In the constructor, have mFilteredData be a new instance copied from mData

mFilteredData = new ArrayList(mData);

Additionally in the Filter, you'll need to update the corresponding code to the follow:

if (TextUtils.isEmpty(constraint)) {
    results.count = mData.size();
    results.values = new ArrayList(mData);
}

Then your getView() method should be pulling from mFilteredData instead of mData. Ideally though, the getView() method should be using the getItem(position) method to access the data. That way, if you change implementation details of where the data is accessed from, you don't have to remember to update the getView() method separately.

Finally as a side note, your filtering code works only because the adapter does not mutate mFilteredData or mData. Normally, one must heavily synchronize the filtering process and other parts of the adapter because performFiltering() occurs on a background thread. If you plan on adding support for modifying the adapter's data after constructing...then you'll need to start adding synchronized blocks.




回答2:


You are modifying the array that contains the original data, and when de Adapter recreates the list, the array has no data.

The correct thing to do this is to create a copy of the original array, and return the copy as the result every time the list is filtered, leaving the original data untouched. A very good example can be found in the ArrayAdapter implementation. See the source code here.

I'll include a copy of the source code here just in case:

/**
 * <p>An array filter constrains the content of the array adapter with
 * a prefix. Each item that does not start with the supplied prefix
 * is removed from the list.</p>
 */
private class ArrayFilter extends Filter {
    @Override
    protected FilterResults performFiltering(CharSequence prefix) {
        FilterResults results = new FilterResults();
        if (mOriginalValues == null) {
            synchronized (mLock) {
                mOriginalValues = new ArrayList<T>(mObjects);
            }
        }
        if (prefix == null || prefix.length() == 0) {
            ArrayList<T> list;
            synchronized (mLock) {
                list = new ArrayList<T>(mOriginalValues);
            }
            results.values = list;
            results.count = list.size();
        } else {
            String prefixString = prefix.toString().toLowerCase();
            ArrayList<T> values;
            synchronized (mLock) {
                values = new ArrayList<T>(mOriginalValues);
            }
            final int count = values.size();
            final ArrayList<T> newValues = new ArrayList<T>();
            for (int i = 0; i < count; i++) {
                final T value = values.get(i);
                final String valueText = value.toString().toLowerCase();
                // First match against the whole, non-splitted value
                if (valueText.startsWith(prefixString)) {
                    newValues.add(value);
                } else {
                    final String[] words = valueText.split(" ");
                    final int wordCount = words.length;
                    // Start at index 0, in case valueText starts with space(s)
                    for (int k = 0; k < wordCount; k++) {
                        if (words[k].startsWith(prefixString)) {
                            newValues.add(value);
                            break;
                        }
                    }
                }
            }
            results.values = newValues;
            results.count = newValues.size();
        }
        return results;
    }
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        //noinspection unchecked
        mObjects = (List<T>) results.values;
        if (results.count > 0) {
            notifyDataSetChanged();
        } else {
            notifyDataSetInvalidated();
        }
    }


来源:https://stackoverflow.com/questions/31014764/filter-list-not-reappearing-after-empty-view-shown

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!