突出显示ListView项目中的搜索文本

时间:2014-05-28 07:14:48

标签: android string listview search

enter image description here

我有ListView我正在使用自定义适配器来显示数据。现在我想改变搜索文本字母颜色,如上面的屏幕截图所示。

以下是SearchView

的代码
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.actionbar_menu_item, menu);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    final SearchView searchView = (SearchView) menu.findItem(R.id.action_search)
            .getActionView();
    searchView.setSearchableInfo(searchManager
            .getSearchableInfo(getComponentName()));
    searchView.setOnQueryTextListener(this);
        return super.onCreateOptionsMenu(menu);
        }

public boolean onQueryTextChange(String newText) {
    // this is adapter that will be filtered
      if (TextUtils.isEmpty(newText)){
            lvCustomList.clearTextFilter();
      }
      else{
            lvCustomList.setFilterText(newText.toString());
       }
    return false;
 }

@Override
public boolean onQueryTextSubmit(String query) {
    return false;
}

谢谢。

3 个答案:

答案 0 :(得分:26)

我假设你有一个自定义适配器,getCount()getView()已经实现并且已经过滤了项目,你只需要加粗部分。

要实现这一点,您需要使用SpannableString,它基本上是带有标记的文本。例如,TextAppearanceSpan可用于更改字体,字体样式,大小和颜色。

因此,您应该更新适配器的getView(),以便将使用textView.setText()的部分更改为或多或少的内容:

String filter = ...;
String itemValue = ...;

int startPos = itemValue.toLowerCase(Locale.US).indexOf(filter.toLowerCase(Locale.US));
int endPos = startPos + filter.length();

if (startPos != -1) // This should always be true, just a sanity check
{
    Spannable spannable = new SpannableString(itemValue);
    ColorStateList blueColor = new ColorStateList(new int[][] { new int[] {}}, new int[] { Color.BLUE });
    TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, blueColor, null);

    spannable.setSpan(highlightSpan, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    textView.setText(spannable);
}
else
    textView.setText(itemValue);

答案 1 :(得分:0)

Android搜索突出示例[案例不敏感订单]

1。 简单搜索(Html): [特定字词]

public static void setSearchTextHighlightSimpleSpannable(TextView textView, String fullText, String searchText) {

    searchText = searchText.replace("'", "");

    // highlight search text
    if (null != searchText && !searchText.isEmpty()) {

        SpannableStringBuilder wordSpan = new SpannableStringBuilder(fullText);
        Pattern p = Pattern.compile(searchText, Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(fullText);
        while (m.find()) {

            int wordStart = m.start();
            int wordEnd = m.end();

            // Now highlight based on the word boundaries
            ColorStateList redColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{0xffa10901});
            TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, redColor, null);

            wordSpan.setSpan(highlightSpan, wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            wordSpan.setSpan(new BackgroundColorSpan(0xFFFCFF48), wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            wordSpan.setSpan(new RelativeSizeSpan(1.25f), wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        }

        textView.setText(wordSpan, TextView.BufferType.SPANNABLE);

    } else {
        textView.setText(fullText);
    }
}

2。 简单搜索(可跨越): [特定字词]

public static void setAdvancedTitleHighlight(TextView textView, String fullText, String searchText) {

    searchText = searchText.replace("'", "");

    final String WORD_SINGLE = " ";

    // highlight search text
    if (null != searchText && !searchText.isEmpty() && !searchText.equals(WORD_SINGLE)) {

        SpannableStringBuilder wordSpan = new SpannableStringBuilder(fullText);
        Pattern p = Pattern.compile(searchText, Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(fullText);
        while (m.find()) {

            final char WORD_BOUNDARY = ' ';

            int wordStart = m.start();
            while (wordStart >= 0 && fullText.charAt(wordStart) != WORD_BOUNDARY) {
                --wordStart;
            }
            wordStart = wordStart + 1;

            int wordEnd = m.end();
            while (wordEnd < fullText.length() && fullText.charAt(wordEnd) != WORD_BOUNDARY) {
                ++wordEnd;
            }

            // Now highlight based on the word boundaries
            ColorStateList redColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{0xffa10901});
            TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, redColor, null);

            wordSpan.setSpan(highlightSpan, wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            wordSpan.setSpan(new BackgroundColorSpan(0xFFFCFF48), wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            wordSpan.setSpan(new RelativeSizeSpan(1.25f), wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        }

        textView.setText(wordSpan, TextView.BufferType.SPANNABLE);

    } else {
        textView.setText(fullText);
    }
}

3。 快速搜索(高级): [全字]

public static void setAdvancedDetailsHighlight(TextView textView, String fullText, String searchText) {

    searchText = searchText.replace("'", "");

    final String WORD_SINGLE = " ";
    final String WORD_SINGLE1 = "\n";
    final String WORD_SINGLE2 = "(";
    final String WORD_SINGLE3 = ")";
    final String WORD_SINGLE4 = "।";
    final String WORD_SINGLE5 = ".";
    final String WORD_SINGLE6 = ",";
    final String WORD_SINGLE7 = ";";
    final String WORD_SINGLE8 = "?";
    final String WORD_SINGLE9 = "-";
    final String WORD_SINGLE10 = "+";

    // highlight search text
    if (null != searchText && !searchText.isEmpty() && !searchText.equals(WORD_SINGLE) && !searchText.equals(WORD_SINGLE1) && !searchText.equals(WORD_SINGLE2)
            && !searchText.equals(WORD_SINGLE3) && !searchText.equals(WORD_SINGLE4) && !searchText.equals(WORD_SINGLE5)
            && !searchText.equals(WORD_SINGLE6) && !searchText.equals(WORD_SINGLE7) && !searchText.equals(WORD_SINGLE8)
            && !searchText.equals(WORD_SINGLE9) && !searchText.equals(WORD_SINGLE10)) {

        SpannableStringBuilder wordSpan = new SpannableStringBuilder(fullText);
        Pattern p = Pattern.compile(searchText, Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(fullText);
        while (m.find()) {

            final char WORD_BOUNDARY = ' ';
            final char WORD_BOUNDARY1 = '\n';
            final char WORD_BOUNDARY2 = '(';
            final char WORD_BOUNDARY3 = ')';
            final char WORD_BOUNDARY4 = '।';
            final char WORD_BOUNDARY5 = '.';
            final char WORD_BOUNDARY6 = ',';
            final char WORD_BOUNDARY7 = ';';
            final char WORD_BOUNDARY8 = '?';
            final char WORD_BOUNDARY9 = '-';

            int wordStart = m.start();
            while (wordStart >= 0 && fullText.charAt(wordStart) != WORD_BOUNDARY
                    && fullText.charAt(wordStart) != WORD_BOUNDARY1
                    && fullText.charAt(wordStart) != WORD_BOUNDARY2
                    && fullText.charAt(wordStart) != WORD_BOUNDARY3
                    && fullText.charAt(wordStart) != WORD_BOUNDARY4
                    && fullText.charAt(wordStart) != WORD_BOUNDARY5
                    && fullText.charAt(wordStart) != WORD_BOUNDARY6
                    && fullText.charAt(wordStart) != WORD_BOUNDARY7
                    && fullText.charAt(wordStart) != WORD_BOUNDARY8
                    && fullText.charAt(wordStart) != WORD_BOUNDARY9) {
                --wordStart;
            }
            wordStart = wordStart + 1;

            int wordEnd = m.end();
            while (wordEnd < fullText.length() && fullText.charAt(wordEnd) != WORD_BOUNDARY
                    && fullText.charAt(wordEnd) != WORD_BOUNDARY1
                    && fullText.charAt(wordEnd) != WORD_BOUNDARY2
                    && fullText.charAt(wordEnd) != WORD_BOUNDARY3
                    && fullText.charAt(wordEnd) != WORD_BOUNDARY4
                    && fullText.charAt(wordEnd) != WORD_BOUNDARY5
                    && fullText.charAt(wordEnd) != WORD_BOUNDARY6
                    && fullText.charAt(wordEnd) != WORD_BOUNDARY7
                    && fullText.charAt(wordEnd) != WORD_BOUNDARY8
                    && fullText.charAt(wordEnd) != WORD_BOUNDARY9) {
                ++wordEnd;
            }

            // Now highlight based on the word boundaries
            ColorStateList redColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{0xffa10901});
            TextAppearanceSpan highlightSpan = new TextAppearanceSpan(null, Typeface.BOLD, -1, redColor, null);

            wordSpan.setSpan(highlightSpan, wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            wordSpan.setSpan(new BackgroundColorSpan(0xFFFCFF48), wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            wordSpan.setSpan(new RelativeSizeSpan(1.25f), wordStart, wordEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        }

        textView.setText(wordSpan, TextView.BufferType.SPANNABLE);

    } else {
        textView.setText(fullText);
    }
}

4. 详情搜索(高级): [全字]

{{1}}

如果你使用任何一种方法,你的问题就会解决...... IngShaaAllah。

答案 2 :(得分:0)

您可以使用 CodeView 库来实现此功能,您只需要在适配器中创建 2 个变量来存储搜索结果的模式和突出显示的颜色,

TEXTURE3

并在适配器中为图案和颜色创建一个 setter

private Pattern syntaxPattern;
private Color highlightColor = Color.MAGENTA;

然后在 RecyclerAdapter 中的 ArrayAdapter 或 ViewHolder 的 getView 方法中,您需要将此模式添加到 CodeView 实例并删除旧模式(从上次搜索结果中)

public void updateSyntaxPattern(Pattern pattern) {
    syntaxPattern = pattern;
    notifyDataSetChanged();
}

现在在 SearchView onQueryTextSubmit 或 onQueryTextChange 中,取决于您希望荧光笔何时工作,您将选择其中之一来从搜索结果中制作模式并将其设置为适配器

if(syntaxPattern != null) {
    codeView.resetSyntaxPatternList();
    codeView.addSyntaxPattern(syntaxPattern, highlightColor);
}

它会像你想要的那样工作

enter image description here