Heim  >  Artikel  >  Java  >  Warum wird die Hervorhebung von Suchtext in RecyclerView mithilfe von ListAdapter auf einigen CardViews nicht korrekt angezeigt?

Warum wird die Hervorhebung von Suchtext in RecyclerView mithilfe von ListAdapter auf einigen CardViews nicht korrekt angezeigt?

Susan Sarandon
Susan SarandonOriginal
2024-11-13 01:00:02885Durchsuche

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

Android: Beheben des Problems mit der Hervorhebung von ForegroundColorSpan-Suchtext mit RecyclerView und ListAdapter

Problembeschreibung

Eine RecyclerView-Liste von CardViews ist befindet sich unter einer Suchansicht in einer Symbolleiste. Die Hervorhebung von Suchtext mit Color.GREEN soll in der onBindViewHolder()-Methode des ListAdapters implementiert werden. Das erste CardView in der RecyclerView-Liste und andere nachfolgende CardViews zeigen jedoch oft keinen hervorgehobenen Text an, was die Sichtbarkeit des Suchtexts beeinträchtigt. Dieses Problem hängt möglicherweise mit der Verwendung von ListAdapter als Adapter zusammen.

Code Snippets

MainActivity

@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);
  }
}

Lösung

Um das Hervorhebungsproblem zu beheben, muss eine entscheidende Änderung vorgenommen werden Die setFilter-Methode von 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);
  }
}

Durch das Hinzufügen einer setSearchString-Methode zum Kartenmodell und das Festlegen ihres Werts beim Filtern lösen wir eine Datenänderung aus, die den Aufruf der onBindViewHolder()-Methode veranlasst und anschließend den Suchtext aktualisiert Hervorhebung.

Das obige ist der detaillierte Inhalt vonWarum wird die Hervorhebung von Suchtext in RecyclerView mithilfe von ListAdapter auf einigen CardViews nicht korrekt angezeigt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn