Rumah >Java >javaTutorial >Mengapakah teks carian yang diserlahkan dalam RecyclerView menggunakan ListAdapter gagal dipaparkan dengan betul pada beberapa CardViews?

Mengapakah teks carian yang diserlahkan dalam RecyclerView menggunakan ListAdapter gagal dipaparkan dengan betul pada beberapa CardViews?

Susan Sarandon
Susan Sarandonasal
2024-11-13 01:00:02969semak imbas

Why is search text highlighting in RecyclerView using ListAdapter failing to display correctly on some CardViews?

Android: Menyelesaikan Isu Penyerlahan Teks Carian ForegroundColorSpan dengan RecyclerView dan ListAdapter

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn