最近公司提出了这样一个需求,实现一个商城动态搜索的功能,大概效果如下:
可能不太清晰,高清的付费,大家凑合看看效果,下面来讲实现步骤
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'