Android搜索框的关键字高亮变色(解决部分产生颜色无效问题)

目前在很多App里面都有搜索的功能,搜索的结果列表要与输入的文字对应高亮,也就是关键字显示高亮,关键字显示相应的颜色,这样会使app体验更好。在此我从网上各种搜索资料,目前参考别人大神的思路和写法,模仿与总结一个工具和自定义TextView。

第一种方式:也是比较方便的一种方式。在此借鉴前人的写法,添加了自己的注意点注意:请使用ContextCompat.getColor获取颜色值,不然会出现颜色失效。

import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.text.Html;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 文字变色工具类
 */
public class wordUtil {

    /**
     * 关键字高亮变色
     * @param context 上下文
     * @param color   变化的色值
     * @param text    文字
     * @param keyword 文字中的关键字
     * @return 结果SpannableString
     */
    public static SpannableString matcherSearchTitle(Context context, int color, String text, String keyword) {
        SpannableString s = new SpannableString(text);
        keyword = escapeExprSpecialWord(keyword);
        text = escapeExprSpecialWord(text);
        if (text.contains(keyword) && !TextUtils.isEmpty(keyword)) {
            try {
                Pattern p = Pattern.compile(keyword);
                Matcher m = p.matcher(s);
                while (m.find()) {
                    int start = m.start();
                    int end = m.end();
                    //注意:请使用ContextCompat.getColor获取颜色值。
                    s.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, color)), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            } catch (Exception e) {
                Log.e("错误:", e.toString());
            }
        }
        return s;
    }

    /**
     * 转义正则特殊字符 ($()*+.[]?\^{},|)
     *
     * @param keyword
     * @return keyword
     */
    public static String escapeExprSpecialWord(String keyword) {
        if (!TextUtils.isEmpty(keyword)) {
            String[] fbsArr = {"\\", "$", "(", ")", "*", "+", ".", "[", "]", "?", "^", "{", "}", "|"};
            for (String key : fbsArr) {
                if (keyword.contains(key)) {
                    keyword = keyword.replace(key, "\\" + key);
                }
            }
        }
        return keyword;
    }

    /**
     * 通过Html.fromHtml方式修改颜色(解决SDK版本问题)
     *
     * @param html
     * @return
     */
    public static Spanned fromHtml(String html) {
        Spanned result;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            result = Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
        } else {
            result = Html.fromHtml(html);
        }
        return result;
    }

    /**
     * 字体颜色修改
     * @param content
     * @param color
     * @return
     */
    public static String color(String content,int color){
        return "" +content + "";
    }

    /**
     * 加粗字体
     * @param content
     * @return
     */
    public static String bold(String content){
        return ""+content+"";
    }
}

第二种方式:自定义TextView:


 
import java.util.ArrayList;
import java.util.List;
 
import android.content.Context;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.widget.TextView;
 
public class MyTextView extends TextView {
 
public MyTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
}
 
public void setSpecifiedTextsColor(String text, String specifiedTexts, int color) {
    List sTextsStartList = new ArrayList();
 
    int sTextLength = specifiedTexts.length();
    String temp = text;
    int lengthFront = 0;//记录被找出后前面的字段的长度
    int start = -1;
    do {
        start = temp.indexOf(specifiedTexts);
 
        if (start != -1) {
            start = start + lengthFront;
            sTextsStartList.add(start);
            lengthFront = start + sTextLength;
            temp = text.substring(lengthFront);
        }
 
    } while (start != -1);
 
    SpannableStringBuilder styledText = new SpannableStringBuilder(text);
    for (Integer i : sTextsStartList) {
        styledText.setSpan(
                new ForegroundColorSpan(color),
                i,
                i + sTextLength,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
 
    setText(styledText);
}

总结:不管是哪种方式,都是注意要使用V4的兼容包Context获取颜色值,因为在某些部分页面代码使用到了V7的兼容包。ForegroundColorSpan创建时直接传入Color的值,由于兼容性,颜色的现实可能会不显示。

你可能感兴趣的:(Android)