Perihalan Masalah
Senarai RecyclerView bagi CardViews terletak di bawah SearchView dalam Toolbar. Penyerlahan teks carian dengan Color.GREEN bertujuan untuk dilaksanakan dalam kaedah onBindViewHolder() ListAdapter. Walau bagaimanapun, CardView pertama dalam senarai RecyclerView dan CardViews seterusnya yang lain sering gagal untuk memaparkan teks yang diserlahkan, menghalang keterlihatan teks carian. Isu ini mungkin dikaitkan dengan menggunakan ListAdapter sebagai Penyesuai.
Kod Coretan
Aktiviti Utama
@Override public boolean onCreateOptionsMenu(Menu menu) { mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return false; } @Override public boolean onQueryTextChange(String newText) { filter(newText); return false; } }); return true; } private void filter(String searchText) { ArrayList<Card> searchList = new ArrayList<>(); for (Card cardItem : mCards) { if (cardItem.getTodo().toLowerCase(Locale.US).contains(searchText)) { searchList.add(cardItem); } } if (!searchList.isEmpty()) { adapter.setFilter(searchList, searchText); } }
ListAdapter
public class CardRVAdapter extends ListAdapter<Card, CardRVAdapter.ViewHolder> { private String searchString = ""; public Spannable spannable; public void setFilter(List<Card> newSearchList, String adapSearchText) { if (newSearchList != null && !newSearchList.isEmpty()) { this.searchString = adapSearchText.toLowerCase(Locale.US); ArrayList<Card> tempList = new ArrayList<>(newSearchList); submitList(tempList); } } public class ViewHolder extends RecyclerView.ViewHolder { TextView carBlankText2; // displays text in the CardView and is matched against the search text input. ForegroundColorSpan fcs = new ForegroundColorSpan(Color.GREEN); public ForegroundColorSpan getFCS() { return fcs; } } public ViewHolder(@NonNull final View itemView) { super(itemView); cardBlankText2 = itemView.findViewById(R.id.cardBlankText2); } void bindData(Card card, final int position) { spannable = Spannable.Factory.getInstance().newSpannable(cardBlankText2.getText().toString()); // Get any previous spans and remove them ForegroundColorSpan[] foregroundSpans = spannable.getSpans(0, spannable.length(), ForegroundColorSpan.class); for (ForegroundColorSpan span : foregroundSpans) { spannable.removeSpan(span); } // Highlight matches from search characters is Green color. if (searchString != null && !TextUtils.isEmpty(searchString)) { int index = spannable.toString().toLowerCase(Locale.US).indexOf(searchString); while (index != -1) { spannable.setSpan(getFCS(), index, index + searchString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); index = spannable.toString().indexOf(searchString, index + searchString.length()); } cardBlankText2.setText(spannable, TextView.BufferType.SPANNABLE); } } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { final Card card = getCardAt(position); if (card != null) { holder.bindData(card, position); } } public Card getCardAt(int position) { return getItem(position); } }
Penyelesaian
Untuk membetulkan isu yang diketengahkan, a perubahan penting mesti dibuat pada kaedah setFilter ListAdapter:
public void setFilter(List<Card> newSearchList, String adapSearchText) { if (newSearchList != null && !newSearchList.isEmpty()) { ArrayList<Card> tempList = new ArrayList<>(); for (Card card: newSearchList) { card.setSearchString(adapSearchText.toLowerCase(Locale.US)); tempList.add(card); } submitList(tempList); } }
Dengan menambahkan kaedah setSearchString pada model Kad dan menetapkan nilainya semasa menapis, kami mencetuskan perubahan data yang menggesa kaedah onBindViewHolder() menjadi dipanggil, kemudian mengemas kini penyerlahan teks carian.
Atas ialah kandungan terperinci Mengapakah teks carian yang diserlahkan dalam RecyclerView menggunakan ListAdapter gagal dipaparkan dengan betul pada beberapa CardViews?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!