问题描述
CardView 的 RecyclerView 列表是位于工具栏中的 SearchView 下方。使用 Color.GREEN 突出显示搜索文本旨在在 ListAdapter 的 onBindViewHolder() 方法中实现。然而,RecyclerView 列表中的第一个 CardView 和其他后续 CardView 通常无法显示突出显示的文本,从而阻碍了搜索文本的可见性。此问题可能与使用 ListAdapter 作为适配器有关。
代码片段
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); } }
解决方案
纠正突出显示问题,必须对 ListAdapter 的 setFilter 方法进行关键更改:
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); } }
通过向 Card 模型添加 setSearchString 方法并在过滤时设置其值,我们触发数据更改,提示 onBindViewHolder( ) 方法被调用,随后更新搜索文本突出显示。
以上是为什么使用 ListAdapter 在 RecyclerView 中突出显示的搜索文本无法在某些 CardView 上正确显示?的详细内容。更多信息请关注PHP中文网其他相关文章!