0

This is my adapter class:

public class adapter_cgpa extends RecyclerView.Adapter<adapter_cgpa.Viewholder> implements Filterable {

ArrayList<POJO> cgpaArrayList;
ArrayList<POJO> cgpaArrayListcopy;
String filterPattern = "";


public adapter_cgpa(ArrayList<POJO> cgpaArrayList) {
    this.cgpaArrayList = cgpaArrayList;
    cgpaArrayListcopy = new ArrayList<>(cgpaArrayList);
}

@NonNull
@Override
public adapter_cgpa.Viewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View listitem = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_cgpa, parent, false);
    return new Viewholder(listitem);
}

@Override
public void onBindViewHolder(@NonNull adapter_cgpa.Viewholder holder, int position) {
    POJO cgpa = cgpaArrayList.get(position);

    if (!filterPattern.equals("")) {
        String tmpCname = cgpa.getCname();
        int startPos = tmpCname.toLowerCase(Locale.US).indexOf(filterPattern.toLowerCase(Locale.US));
        int endPos = startPos + filterPattern.length();
        if (startPos != -1) {
            Spannable spannable = new SpannableString(tmpCname);
            ColorStateList blueColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{Color.BLUE});
            TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, blueColor, null);
            spannable.setSpan(highlightSpan, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            holder.cname.setText(spannable);
        } else {
            holder.cname.setText(cgpa.getCname());
        }
    } else {
        holder.cname.setText(cgpa.getCname());
    }

    holder.no_of_sems.setText(cgpa.getNo_of_sems());
    holder.cgpa.setText(cgpa.getCgpa());
    holder.percentage.setText(cgpa.getPercentage());
    holder.schemec.setText(cgpa.getSchemec());

}

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


@Override
public Filter getFilter() {
    return new Filter() {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            List<POJO> filteredList = new ArrayList<>();

            if (TextUtils.isEmpty(constraint)) {
                filterPattern="";
                filteredList.addAll(cgpaArrayListcopy);
            } else {
                filterPattern = constraint.toString().toLowerCase().trim();
                for (POJO item : cgpaArrayListcopy) {
                    if (item.getCname().toLowerCase().contains(filterPattern)) {
                        filteredList.add(item);
            //        } else {
            //            filteredList.remove(item);
                    }
                }
            }

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

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

            cgpaArrayList.clear();
            cgpaArrayList.addAll((List) results.values);
            notifyDataSetChanged();
        }

    };

}


public class Viewholder extends RecyclerView.ViewHolder {
    TextView cname, no_of_sems, cgpa, percentage, schemec;
    ImageButton btndelete2;

    public Viewholder(@NonNull View itemView) {
        super(itemView);
        cname = itemView.findViewById(R.id.name);
        no_of_sems = itemView.findViewById(R.id.no_of_sem);
        cgpa = itemView.findViewById(R.id.textView49);
        percentage = itemView.findViewById(R.id.textView55);
        schemec = itemView.findViewById(R.id.scheme2);
        btndelete2 = itemView.findViewById(R.id.btndelete2);

        btndelete2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                final AlertDialog.Builder alert = new AlertDialog.Builder(v.getContext());
                alert.setMessage("Are you sure you want to delete this?");

                alert.setNegativeButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {

                    }
                });
                alert.setPositiveButton("No", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {

                    }
                });
                final AlertDialog dialogs = alert.create();
                dialogs.show();
                dialogs.getButton(androidx.appcompat.app.AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                        delete(getAdapterPosition());
                        dialogs.dismiss();

                    }
                });
                dialogs.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                        dialogs.dismiss();
                    }
                });
            }
        });

    }


    private void delete(int adapterPosition) {

        cgpaArrayList.remove(adapterPosition);
        notifyDataSetChanged();
        final String snc = cname.getText().toString();
        final String semrc = no_of_sems.getText().toString();
        final String schc = schemec.getText().toString();

        dbmanager db = new dbmanager(itemView.getContext());
        db.delete2(snc, semrc, schc);
    }
}

And this is my cgpa_frag fragment:

public class cgpa_frag extends Fragment {

    RecyclerView recyclerview;
    adapter_cgpa ac;
    TextView tv_noContent2;

    ArrayList<POJO> cgpaArrayList = new ArrayList<>();

    public cgpa_frag() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

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

        setHasOptionsMenu(true);

        View view = inflater.inflate(R.layout.fragment_cgpa_frag, container, false);
        recyclerview = (RecyclerView) view.findViewById(R.id.rc2);
        tv_noContent2 = (TextView)view.findViewById(R.id.tv_noContent2);
        cgpaArrayList = new ArrayList<>();
        Fetchdata2();
        ac = new adapter_cgpa(cgpaArrayList);
        recyclerview.setLayoutManager(new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false));
        if(cgpaArrayList.isEmpty()){
            recyclerview.setVisibility(View.GONE);
            tv_noContent2.setVisibility(View.VISIBLE);
            tv_noContent2.setText("Look's like you have not saved any CGPA calculation.");

        }else{
            tv_noContent2.setVisibility(View.GONE);
            recyclerview.setVisibility(View.VISIBLE);
            recyclerview.setAdapter(ac);
        }

        return view;
    }

    private void Fetchdata2() {
        dbmanager db = new dbmanager(getContext());

        Cursor cursor = db.fetch_data2();

        if (cursor != null) {

            while (cursor.moveToNext()) {

                POJO pj = new POJO();
                pj.setCname(cursor.getString(0));
                pj.setNo_of_sems(cursor.getString(1));
                pj.setCgpa(cursor.getString(2));
                pj.setPercentage(cursor.getString(3));
                pj.setSchemec(cursor.getString(4));
                cgpaArrayList.add(pj);
            }
            // ac = new adapter_cgpa(cgpaArrayList);
        }
    }

    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {

        inflater.inflate(R.menu.search_menu, menu);

        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) searchItem.getActionView();

        searchView.onActionViewExpanded();
        searchView.setIconifiedByDefault(false);
        searchView.setQueryHint("Search by name ... ");

        if(!searchView.isFocused()) {
            searchView.clearFocus();
        }

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                ac.getFilter().filter(newText, new Filter.FilterListener() {
                    @Override
                    public void onFilterComplete(int i) {
                        if(i == 0){
                            recyclerview.setVisibility(View.GONE);
                            tv_noContent2.setVisibility(View.VISIBLE);
                            tv_noContent2.setText("No matching results found");
                        }else{
                            tv_noContent2.setVisibility(View.GONE);
                            recyclerview.setVisibility(View.VISIBLE);
                        }
                    }
                });
                return false;
            }
        });
    }

How can I access filterPattern from getFilter method in bindviewHolder ? I wanted to know how can I access filterPattern from getFilter method in bindviewHolder so that I am able to highlight the matching text patterns in RecyclerView. Can anyone help me with it ? Thanks in advance.

Sneha
  • 94
  • 10
  • https://stackoverflow.com/questions/59628149/how-can-we-have-searched-characters-colored-when-we-use-searchview-in-recyclervi – MMG May 02 '20 at 20:04

1 Answers1

2

Add String filterPattern = ""; after ArrayList<POJO> cgpaArrayListcopy;, then filterPattern can be accessed everywhere in the adapter.

To highlight filtered text, try the following codes:

@Override
public void onBindViewHolder(@NonNull adapter_cgpa.Viewholder holder, int position) {
    POJO cgpa = cgpaArrayList.get(position);

    if (!filterPattern.equals("")) {
        String tmpCname = cgpa.getCname();
        int startPos = tmpCname.toLowerCase(Locale.US).indexOf(filterPattern.toLowerCase(Locale.US));
        int endPos = startPos + filterPattern.length();
        if (startPos != -1) {
            Spannable spannable = new SpannableString(tmpCname);
            ColorStateList blueColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{Color.BLUE});
            TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, blueColor, null);
            spannable.setSpan(highlightSpan, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            holder.cname.setText(spannable);
        } else {
            holder.cname.setText(cgpa.getCname());
        }
    } else {
        holder.cname.setText(cgpa.getCname());
    }

    holder.no_of_sems.setText(cgpa.getNo_of_sems());
    holder.cgpa.setText(cgpa.getCgpa());
    holder.percentage.setText(cgpa.getPercentage());
    holder.schemec.setText(cgpa.getSchemec());
}


        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            List<POJO> filteredList = new ArrayList<>();

            if (TextUtils.isEmpty(constraint)) {
                filterPattern = "";
                filteredList.addAll(cgpaArrayListcopy);
            } else {
                filterPattern = constraint.toString().toLowerCase().trim();
                for (POJO item : cgpaArrayListcopy) {
                    if (item.getCname().toLowerCase().contains(filterPattern)) {
                        filteredList.add(item);
                    //} else {
                    //    filteredList.remove(item);
                    }
                }
            }

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

            return results;
        }

Hope that helps!

enter image description here

i_A_mok
  • 2,744
  • 2
  • 11
  • 15
  • This isn't working as expected.. The colour is not changing. – Sneha May 05 '20 at 06:49
  • I just tried the code and it works for me. Pls check and debug carefully. If the problem still not fixed, update the question with your current adapter code. – i_A_mok May 05 '20 at 09:12
  • ok, then.. Please check my updated code in the question. No matter, what I search now, It always displays "No matching results found" even if there are matching results. – Sneha May 05 '20 at 12:51
  • 1
    Updated the answer. The only change is: added `results.count = filteredList.size();` inside **performFiltering()**. – i_A_mok May 06 '20 at 02:55
  • @i_A_mok Hi, I have a similar use case. How would you change the code above to highlight the search letter or number if there were more two or more of them in the CardView. So for the CardView above that has "11", both would be highlighted, not just the first one. Would appreciate any thoughts or ideas you have. – AJW May 10 '21 at 00:07