0

I am writing ad Adapter class with a Filter and I get this error in publishResults method. The list is loaded, when I type something in filter, it starts filtering, but when deleting chars and reaching 0 length, the app crash with this error, moreover some of imageView (CardView type) are inverted, so maybe I'm doing something wrong in parsing too.

Fragment

public class ColorViewFragment extends Fragment {

    private RecyclerView recyclerView;
    private JSONArray json;
    private ColorListAdapter adapter;

    private EditText editColor;

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

        View view = inflater.inflate(R.layout.color_list, container, false);
        this.recyclerView = view.findViewById(R.id.recyclerView);

        /*
        try {
            this.recyclerView.setAdapter(new ColorListAdapter(this.json));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        */

        try {
            adapter = new ColorListAdapter(json);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        recyclerView.setAdapter(adapter);


        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
        this.recyclerView.setLayoutManager(layoutManager);

        //
        editColor = view.findViewById(R.id.editText);
        editColor.addTextChangedListener(new TextWatcher() {

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

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

                ColorViewFragment.this.adapter.getFilter().filter(s);

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        return view;
    }

    public void setJSON(JSONArray newJson){
        this.json = newJson;
    }


}

Adapter

public class ColorListAdapter extends RecyclerView.Adapter implements Filterable {

    private JSONArray colorList;

    private List<String> colorListFiltered = new ArrayList<String>();

    public ColorListAdapter(JSONArray json) throws JSONException {
        super();
        if (json != null) {
            this.colorList = json;

                for (int i=0;i<json.length();i++){
                    //colorListFiltered.add((colorList.getString(i)));
                    colorListFiltered.add(json.getJSONObject(i).getString("Name"));
                }
        }
    }


    @Override
    public Filter getFilter() {
        return new colorFilter();
    }


    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fragment_color_view, viewGroup, false);
        return new ColorListHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
        try {
            ((ColorListHolder) viewHolder).setContentValue(i);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

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

    private class ColorListHolder extends RecyclerView.ViewHolder {

        private TextView colorCodeText;
        private TextView colorNameText;
        private CardView imageView;

        public ColorListHolder(@NonNull View itemView) {
            super(itemView);
            this.colorCodeText = itemView.findViewById(R.id.colorCode_text);
            this.colorNameText = itemView.findViewById(R.id.colorName_text);
            this.imageView = itemView.findViewById(R.id.colorView);
        }

        public void setContentValue(int index) throws JSONException {

            this.colorNameText.setText(colorListFiltered.get(index));
            //this.colorNameText.setText(((JSONObject) colorList.get(index)).getString("Name"));
            this.colorCodeText.setText(((JSONObject) colorList.get(index)).getString("ColorCode"));
            this.imageView.setCardBackgroundColor(Color.parseColor(((JSONObject) colorList.get(index)).getString("HexString")));

        }
    }


    public class colorFilter extends Filter{

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults Result = new FilterResults();
            // if constraint is empty return the original names
            if(constraint.length() == 0 ){
                Result.values = colorList;
                Result.count = colorList.length();
                return Result;
            }
            else {

                List<String> Filtered_Names = new ArrayList<String>();
                String filterString = constraint.toString().toLowerCase();
                String filterableString = "";

                for (int i = 0; i < colorList.length(); i++) {
                    try {
                        filterableString = (colorList.getJSONObject(i)).getString("Name");
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                    if (filterableString.toLowerCase().contains(filterString)) {
                        Filtered_Names.add(filterableString);
                    }
                }

                Result.values = Filtered_Names;
                Result.count = Filtered_Names.size();
                return Result;

            }

        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

            colorListFiltered = (ArrayList<String>) results.values;
            notifyDataSetChanged();
        }
    }


}

1 Answer 1

1

The problem occurs in your performFiltering(CharSequence constraint) when you return a JSONArray object instead a ArrayList in the first if statement

To fix it do this changes:

 public class colorFilter extends Filter{

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults Result = new FilterResults();
            // if constraint is empty return the original names
            if(constraint.length() == 0 ) {
                ArrayList<String> arrColorList = new ArrayList<>();
                for (int i = 0; i < colorList.length(); i++) {                                                      
                    arrColorList.add(colorList.getJSONObject(i).getString("Name"));
                }
                Result.values = arrColorList;
                Result.count = arrColorList.size();
                return Result;
            }
            else {

                List<String> Filtered_Names = new ArrayList<String>();
                String filterString = constraint.toString().toLowerCase();
                String filterableString = "";

                for (int i = 0; i < colorList.length(); i++) {
                    try {
                        filterableString = (colorList.getJSONObject(i)).getString("Name");
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                    if (filterableString.toLowerCase().contains(filterString)) {
                        Filtered_Names.add(filterableString);
                    }
                }

                Result.values = Filtered_Names;
                Result.count = Filtered_Names.size();
                return Result;

            }

        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

            colorListFiltered = (ArrayList<String>) results.values;
            notifyDataSetChanged();
        }
    }
Sign up to request clarification or add additional context in comments.

1 Comment

You're right, thank you very much. There's only one more problem. Items sometimes are inverted while performing filtering. I think that setContentValue() should be fixed, but it's better in another post here: stackoverflow.com/questions/57134956/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.