如何在使用Android的SearchView小部件时突出显示过滤文本

9

我已经在我的应用程序中实现了SearchView小部件。它正常工作。现在我需要做的是,每当我在我的SearchView Bar中键入一个单词时,过滤后的结果应该突出显示搜索的单词,如下图所示:

enter image description here

我正在使用这个SearchView小部件:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.myMenu , menu);
    MenuItem searchItem = menu.findItem(R.id.action_search);
    SearchView sv = new SearchView(getActivity());

    // Changing the color of Searchview widget text field to white.     
    int searchSrcTextId = getResources().getIdentifier("android:id/search_src_text", null, null);  
    EditText searchEditText = (EditText) sv.findViewById(searchSrcTextId);  
    searchEditText.setTextColor(Color.WHITE); 

    sv.setOnQueryTextListener(this);
    searchItem.setActionView(sv);
    super.onCreateOptionsMenu(menu, inflater);
}

搜索结果是ListView,您需要更改ListView项目的文本颜色。 - Maveňツ
尝试一下这个,它会帮助你:https://dev59.com/0XrZa4cB1Zd3GeqP0kqz - Pandiyan Muthu
如果我更改列表项的颜色,它将更改整行。我只想更改搜索到的字母。 - Ali Ansari
请查看这个答案:https://dev59.com/YGAg5IYBdhLWcg3wLIXS#23967561 我相信它正是你所需要的。 - matiash
3个回答

8
您可以使用Spannable TextView来实现此功能。希望这种方法能够帮到您。

方法:

public static CharSequence highlightText(String search, String originalText) {
    if (search != null && !search.equalsIgnoreCase("")) {
        String normalizedText = Normalizer.normalize(originalText, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "").toLowerCase();
        int start = normalizedText.indexOf(search);
        if (start < 0) {
            return originalText;
        } else {
            Spannable highlighted = new SpannableString(originalText);
            while (start >= 0) {
                int spanStart = Math.min(start, originalText.length());
                int spanEnd = Math.min(start + search.length(), originalText.length());
                highlighted.setSpan(new ForegroundColorSpan(Color.BLUE), spanStart, spanEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                start = normalizedText.indexOf(search, spanEnd);
            }
            return highlighted;
        }
    }
    return originalText;
}

return originalText将会突出显示文本。


int spanStart和int spanEnd是做什么的?它为搜索文本创建一个新的索引整数吗?length()方法在这里起什么作用? - AJW
@influx 你尝试在我的代码执行后调用notifyDatasetchanged()了吗? - John smith

5
你应该在onBindViewHolder()方法中执行此操作(使用RecyclerView)
类YourAdapter
String searchString="";

@Override
    public void onBindViewHolder(AllMessageAdapter.DataObjectHolder holder, final int position) {

        holder.message.setText(mDataset.get(position).Message);

        AllMessageList.Message message=mDataset.get(position);

        String name = message.Message.toLowerCase(Locale.getDefault());

        if (name.contains(searchString)) {

            int startPos = name.indexOf(searchString);
            int endPos = startPos + searchString.length();

            Spannable spanString = Spannable.Factory.getInstance().newSpannable(holder.message.getText());
            spanString.setSpan(new ForegroundColorSpan(Color.RED), startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            holder.message.setText(spanString);
        }

    }

您的筛选器(在适配器中)

public void setFilter(ArrayList<AllMessageList.Message> countryModels,String searchString) {
        this.searchString=searchString;
        mDataset = new ArrayList<>();
        mDataset.addAll(countryModels);
        notifyDataSetChanged();
    }

enter image description here


int endPos是做什么的?它为搜索文本创建一个新的索引整数吗?length()方法在这里有什么作用? - AJW
这是区分大小写的。 - Faizan Mubasher

2
你可以使用这个来突出显示所有关键字。
 button.setOnClickListener(new OnClickListener() {      
      @Override
      public void onClick(View v) {

        String ett = edittext.getText().toString();
        String tvt = textview.getText().toString();
        int ofe = tvt.indexOf(ett, 0);
        Spannable spannable = new SpannableString(tvt);

        for (int ofs = 0; ofs < tvt.length() && ofe != -1; ofs = ofe + 1) {
        ofe = tvt.indexOf(ett, ofs);

                if (ofe == -1)
                    break;
                else {
                  ColorStateList blueColor = new ColorStateList(new nt[][] { new int[] {} }, new int[] { Color.BLUE });
                  TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, blueColor, null);
                  spannable.setSpan(highlightSpan, ofe, ofe+edittext.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                  textview.setText(spannable);
                }
            }
        }
    });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接