安卓实现动态搜索相同字符变色效果

最近公司提出了这样一个需求,实现一个商城动态搜索的功能,大概效果如下:

可能不太清晰,高清的付费,大家凑合看看效果,下面来讲实现步骤

1.控件方面,大的控件仅需一个edittext和一个recycleview,.xml文件如下

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".view.activity.MainActivity">
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_main_1"/>
    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rv_1"/>
</LinearLayout>

2.FindUtil:此工具类为字体变色工具类,包含可实现多种变色效果,如下所示

/**
 * 字体局部变色的工具类
 * */
public class FindUtil {
    /**
     * 关键字高亮变色
     *
     * @param color   变化的色值
     * @param text    文字
     * @param keyword 文字中的关键字
     * @return
     */
    public static SpannableString findSearch(int color, String text, String keyword) {
        SpannableString s = new SpannableString(text);
        Pattern p = Pattern.compile(keyword);
        Matcher m = p.matcher(s);
        while (m.find()) {
            int start = m.start();
            int end = m.end();
            s.setSpan(new ForegroundColorSpan(color), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return s;
    }

    /**
     * 多个关键字高亮变色
     *
     * @param color   变化的色值
     * @param text    父文字
     * @param keyword 切割好的字符组
     * @return
     */
    public static SpannableString findSearch(int color, String text, String[]keyword) {
        SpannableString s = new SpannableString(text);
        for (int i = 0; i < keyword.length; i++) {
            Pattern p = Pattern.compile(keyword[i]);
            Matcher m = p.matcher(s);
            while (m.find()) {
                int start = m.start();
                int end = m.end();
                s.setSpan(new ForegroundColorSpan(color), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        return s;
    }
    /**
     * 将需要改变的字符串切割成字符
     * @param string 需要改色的字符串
     * */
    public static String[] SplitString(String string){
        String[]strings={};
        for (int i=0 ;i<string.length();i++){
            if (i<string.length()){
                String substring = string.substring(i, i + 1);
                strings[i]=substring;
            }
        }
        return strings;
    }

}

3.适配器:适配器和正常的没有太大区别,只是需要多传一个需要变色的字符参数,并在调用FindUntil类

public class ShopAdapter extends RecyclerView.Adapter<ShopAdapter.MyHolder> {
    private Context context;
    private List<ShopBean.ResultDTO> list;
    private String string;

    public ShopAdapter(Context context, List<ShopBean.ResultDTO> list,String s) {
        this.context = context;
        this.list = list;
        this.string=s;
    }

    @NonNull
    @Override
    public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new MyHolder(LayoutInflater.from(context).inflate(R.layout.shop, parent, false));
    }
//清空原有的商品数据,展示新的商品数据
    public  void  isFush(List<ShopBean.ResultDTO>list1){
        this.list.clear();
        this.list.addAll(list1);
        notifyDataSetChanged();
    }

    @Override
    public void onBindViewHolder(@NonNull MyHolder holder, int position) {
     /*
      逐字切割的写法
      String[] strings = FindUtil.SplitString(string);
        if (strings!=null){
            holder.tvItem1.setText(FindUtil.findSearch(Color.RED,list.get(position).commodityName ,strings ));
        }else {
            holder.tvItem1.setText(FindUtil.findSearch(Color.RED,list.get(position).commodityName ,""));
        }*/
        //固定字符变色
        holder.tvItem1.setText(FindUtil.findSearch(Color.RED,list.get(position).commodityName ,string ));
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    class MyHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.tv_item_1)
        TextView tvItem1;
        public MyHolder(@NonNull View itemView) {
            super(itemView);
            ButterKnife.bind(this,itemView);
        }
    }

}

4.activity edit动态监听以及适配器的调用

1.适配器:可封装成一个方法,因为需要传入需要变色的字符串,所以需要多次调用

/**
 * @param strings 需要变色的固定字符
 * */
private void onShow(String strings){
    rv1.setLayoutManager(new LinearLayoutManager(MainActivity.this));//可以放在oncreate里
    adapter=new ShopAdapter(this,list,strings);
    rv1.setAdapter(adapter);
}

2.输入框输入监听:addTextChangedListener

etMain1.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        //获取输入框此时的文字
        String s1 = s.toString();
        if (s1.length()==0){
            //输入框为空的一些操作,这里是直接把recycleview隐藏掉
            rv1.setVisibility(View.GONE);
            onShow("");
        }else {
            //输入框内容改变,传入新的文字,刷新适配器
            rv1.setVisibility(View.VISIBLE);
            onShow(s1);
            getPresenter().onSuccess(s1,"1","5");
        }
    }

    @Override
    public void afterTextChanged(Editable s) {

    }
});

好了,这样就可以实现一个简单的实时搜索相同字体变色效果,新人新文,有问题欢迎随时指正

1.涉及到的依赖:

//    butterknife的依赖 数据绑定
implementation 'com.jakewharton:butterknife:10.2.3'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值