Maison  >  Article  >  Java  >  Pourquoi la mise en surbrillance du texte recherché dans RecyclerView à l'aide de ListAdapter ne s'affiche-t-elle pas correctement sur certaines CardViews ?

Pourquoi la mise en surbrillance du texte recherché dans RecyclerView à l'aide de ListAdapter ne s'affiche-t-elle pas correctement sur certaines CardViews ?

Susan Sarandon
Susan Sarandonoriginal
2024-11-13 01:00:02885parcourir

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

Android : résolution du problème de mise en surbrillance du texte de recherche ForegroundColorSpan avec RecyclerView et ListAdapter

Description du problème

Une liste RecyclerView de CardViews est situé sous un SearchView dans une barre d’outils. La mise en surbrillance du texte de recherche avec Color.GREEN est destinée à être implémentée dans la méthode onBindViewHolder() de ListAdapter. Cependant, le premier CardView de la liste RecyclerView et les autres CardViews suivants ne parviennent souvent pas à afficher le texte en surbrillance, ce qui gêne la visibilité du texte de recherche. Ce problème peut être lié à l'utilisation de ListAdapter comme adaptateur.

Code Extraits

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

Solution

Pour remédier au problème de mise en évidence, un changement crucial doit être apporté au Méthode setFilter de 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);
  }
}

En ajoutant une méthode setSearchString au modèle Card et en définissant sa valeur lors du filtrage, nous déclenchons une modification des données qui invite à appeler la méthode onBindViewHolder(), mettant ensuite à jour le texte de recherche. mise en évidence.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn