0

I have been working on a search feature which will enable me to search the data in my RecyclerView. My app crashes when I click on the search icon. After some debugging I found the issue, cannot seem to clear or add information to a new List.

AdapterClass.java

public class JobAdapter extends RecyclerView.Adapter<JobAdapter.ViewHolder> implements Filterable {

    private OnJobClickListener mListener;
    private List<Job> jobs;
    private List<Job> jobsListFiltered;

    private static final String LOG_TAG = JobAdapter.class.getName();


    public interface OnJobClickListener {
        void onJobClick(Job job);
    }

    public void setOnItemClickListener(OnJobClickListener listener) {
        mListener = listener;
    }

    // Provide a reference to the views for each data item
    // Provide access to all the views for a data item in a view holder
    public class ViewHolder extends RecyclerView.ViewHolder {

        public TextView jobTitle;
        public TextView companyName;
        public TextView datePosted;
        public ImageView companyLogo;
        public View layout;


        public ViewHolder(View itemView) {
            super(itemView);
            layout = itemView;
            jobTitle = layout.findViewById(R.id.textView_job_title);
            companyName = layout.findViewById(R.id.textView_company_name);
            datePosted = layout.findViewById(R.id.textView_date);
            companyLogo = layout.findViewById(R.id.imageViewLogo);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (mListener != null) {
                        int position = getAdapterPosition();
                        if (position != RecyclerView.NO_POSITION) {
                            Job currentJob = jobs.get(position);
                            mListener.onJobClick(currentJob);
                        }
                    }
                }
            });
        }
    }


    // Job constructor
    public JobAdapter(List<Job> job, OnJobClickListener listener) {
        jobs = job.subList(1, job.size());
        this.mListener = listener;
        jobsListFiltered = new ArrayList<>(job);
    }

    // Create new views (invoked by the layout manager)
    @Override
    public JobAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // create a new view
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View v = inflater.inflate(R.layout.job_item_row, parent, false);

        // set the view's size, margins, paddings and layout parameters
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // Get element from the dataset at this position
        // Replace the contents of the view with that element
        Job currentJob = jobs.get(position);

        String mJobTitle = currentJob.getJobTitle();
        holder.jobTitle.setText(mJobTitle);

        String mCompanyName = currentJob.getCompanyName();
        holder.companyName.setText(mCompanyName);

        Context context = holder.datePosted.getContext();

        Date mDatePosted = currentJob.getDatePosted();
        String dateFormat = formatDayMonth(context, mDatePosted);
        holder.datePosted.getContext();
        holder.datePosted.setText(dateFormat);

        String mCompanyLogo = currentJob.getCompanyLogo();
        RequestOptions requestOptions = new RequestOptions()
                .placeholder(R.drawable.ic_launcher_foreground)
                .circleCrop();
        Glide.with(context)
                .load(mCompanyLogo)
                .apply(requestOptions)
                .into(holder.companyLogo);
    }

        @Nullable
        public static String formatDayMonth (@NonNull Context context, @Nullable Date date){
            if (date == null) {
                return null;
            }

            SimpleDateFormat sdf = new SimpleDateFormat(
                    context.getString(R.string.format_date),
                    Locale.US);
            return sdf.format(date);
        }

        public int getItemCount () {
            return (jobs != null) ? jobs.size() : 0;
        }

    @Override
    public Filter getFilter() {
        return jobFilter;
    }

    private Filter jobFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            List<Job> filteredList = new LinkedList<>();

            if (constraint == null || constraint.length() == 0) {
                filteredList.addAll(jobsListFiltered);
            } else {
                String filterPattern = constraint.toString().toLowerCase().trim();

                for (Job job : jobsListFiltered) {
                    if (job.getJobTitle().toLowerCase().contains(filterPattern)) {
                        filteredList.add(job);
                    }
                }
            }

            FilterResults results = new FilterResults();
            results.values = filteredList;

            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            jobs.clear();
            jobs.addAll((LinkedList)results.values);
            notifyDataSetChanged();
        }
    };

}

Error:

E/AndroidRuntime: FATAL EXCEPTION: main Process: packagename, PID: 17390 java.lang.UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:161) at java.util.AbstractList$Itr.remove(AbstractList.java:374) at java.util.AbstractList.removeRange(AbstractList.java:571) at java.util.SubList.removeRange(AbstractList.java:668) at java.util.AbstractList.clear(AbstractList.java:234) at packagename.JobAdapter$1.publishResults(JobAdapter.java:178) at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

So far I tried out the suggestions from this thread but they don't seem to be working for my situation. Any help will be appreciated ;)

allycat
  • 115
  • 5

1 Answers1

2

Please show the code that calls your JobAdapter constructor.

In the JobAdapter constructor, you are using List.subList to create a sublist view backed by the original list. As such, your sublist will inherit whatever properties were on the backing list (like immutability.)

The stack trace clearly shows you are trying to clear a list that cannot be cleared which I can only assume is because it is immutable.

To get around this you can create a new ArrayList from the sublist in your JobAdapter constructor like this:

jobs = new ArrayList<>(job.subList(1, job.size()));
Michael Krause
  • 4,689
  • 1
  • 21
  • 25