User3
User3

Reputation: 2535

Recycler view does not refresh on filter - ArrayAdapter

I have an edit text and a recycler view, what I intend of the edit text is to use the input as a filter on the list. Here is my code:

Fragment:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.frag_trains_view, container, false);

        mountain.customwidgets.MontserratRegularAutoComplete editStationSearch =
                (mountain.customwidgets.MontserratRegularAutoComplete)
                        view.findViewById(R.id.autoCompleteSource);

        editStationSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                mAdapter.getFilter().filter(s);

            }
        });


        RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
        CsvReaderImpl csvReader = new CsvReaderImpl();
        stationNameCodePojoArrayList = csvReader.ReadFromfile("data/stations.txt", getActivity());

        mAdapter = new StationsRecyclerAdapter(getActivity(),stationNameCodePojoArrayList);
        mRecyclerView.setAdapter(mAdapter);

        LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(mLayoutManager);

        mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL) {
            @Override
            public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
                // Do not draw the divider
            }
        });

        return view;

    }

Here is my adapter class:

public class StationsRecyclerAdapter extends RecyclerView.Adapter<StationsRecyclerAdapter.DataObjectHolder> implements Filterable {

    private ArrayList<StationPojo> mDataset;
    private StationTextFilter stationTextFilter;
    private Context ctx;

    public StationsRecyclerAdapter(Context ctx, ArrayList<StationPojo> myDataset) {
        this.mDataset = (new ArrayList<>(myDataset));
        this.ctx = ctx;
        for (int i = 0; i < mDataset.size(); i++) {
            System.out.println("mDatasset Original: " + Arrays.asList(mDataset.get(i).getStationName()));
        }
    }

    @Override
    public Filter getFilter() {
        if (stationTextFilter == null) {
            stationTextFilter = new StationTextFilter(this, mDataset);
        }
        return stationTextFilter;
    }

    @Override
    public DataObjectHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View mView = LayoutInflater.from(ctx).inflate(R.layout.row_auto_complete, parent, false);
        return new DataObjectHolder(mView);
    }

    public static class DataObjectHolder extends RecyclerView.ViewHolder {
        TextView stationName;
        TextView stationCode;
        TextView stationElevation;


        public DataObjectHolder(View itemView) {
            super(itemView);
            stationName = (TextView) itemView.findViewById(R.id.textStationName);
            stationCode = (TextView) itemView.findViewById(R.id.textStationCode);
            stationElevation = (TextView) itemView.findViewById(R.id.textStationElevation);
        }
    }

    @Override
    public void onBindViewHolder(DataObjectHolder holder, int position) {
        holder.stationCode.setText(mDataset.get(position).getStationCode());
        holder.stationElevation.setText(mDataset.get(position).getStationElevation());
        holder.stationName.setText(mDataset.get(position).getStationName());

    }

    @Override
    public int getItemCount() {
        return mDataset.size();
    }

    @Override
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }

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

}

And here is the Filter class:

public class StationTextFilter extends Filter {

    private final StationsRecyclerAdapter adapter;
    private List<StationPojo> mDataset;
    private final List<StationPojo> filteredList;

    public StationTextFilter(StationsRecyclerAdapter adapter, List<StationPojo> mDataset) {
        super();
        this.adapter = adapter;
        this.mDataset = new ArrayList<>(mDataset);
        this.filteredList = new ArrayList<>();
    }

    @Override
    protected FilterResults performFiltering(CharSequence charSequence) {
        filteredList.clear();
        final FilterResults results = new FilterResults();

        if (charSequence.length() == 0) {
            filteredList.addAll(mDataset);
        } else {
            final String filterPattern = charSequence.toString().toLowerCase().trim();
            for (StationPojo item : mDataset) {
                if (item.getStationName().toLowerCase().contains(filterPattern)) {
                    filteredList.add(item);
                    System.out.println("Match found Word: " + filterPattern);

                }
            }
        }

        results.values = filteredList;
        results.count = filteredList.size();
        return results;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
        mDataset.clear();
        mDataset.addAll((ArrayList<StationPojo>) filterResults.values);
        for (int i = 0; i < mDataset.size(); i++) {
            System.out.println("mDatasset at filter: " + Arrays.asList(mDataset.get(i).getStationName()));
        }
        adapter.notifyDataSetChanged();
    }
}

I am pretty sure that things work fine till the mDataset.addAll((ArrayList<StationPojo>) filterResults.values); as I can print the filtered results, somehow I am not able to know why notifyDatasetChanged does not work! Any headings?

Upvotes: 2

Views: 895

Answers (1)

Murat Karag&#246;z
Murat Karag&#246;z

Reputation: 37584

Because your Adapter is referencing a different ArrayList and not the one in your StationTextFilter. See here

  public StationTextFilter(StationsRecyclerAdapter adapter, List<StationPojo> mDataset) {
        super();
        this.adapter = adapter;
        this.mDataset = new ArrayList<>(mDataset);
        this.filteredList = new ArrayList<>();
    }

The mDataset is the actual referenced ArrayList in your adapter, but here you are creating an entirely new ArrayList and thus does not get reflected in your notifyDataSetChanged.

One way to solve this is to not create a new ArrayList and use it as it is.

this.mDataset = mDataset;

Upvotes: 2

Related Questions