美文网首页
edittext+recycleview搜索功能

edittext+recycleview搜索功能

作者: jiluyixia | 来源:发表于2019-11-28 10:25 被阅读0次

    实现edittext搜索,Recyclerview+关键字动态匹配筛选变色效果。


    edittext——recycleview.jpg

    先修改search_page.xml,加一个RecyclerView。

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical">
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/shape_edittext"
            android:layout_marginTop="20dp"
            android:layout_marginLeft="10dp"
            android:orientation="horizontal">
    
            <EditText
                android:id="@+id/searchEd"
                android:drawableLeft="@drawable/search_gray"
                android:background="@null"
                android:layout_width="270dp"
                android:layout_height="wrap_content"
                />
            <ImageView
                android:id="@+id/speak"
                android:src="@drawable/audio"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
        </LinearLayout>
        <TextView
            android:text="搜索"
            android:textColor="@android:color/holo_blue_dark"
            android:layout_marginTop="23dp"
            android:paddingLeft="5dp"
            android:textSize="17dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        </LinearLayout>
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/searchRecycle"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>
    </LinearLayout>
    

    设置edittext输入监听:

    searchEd.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) {
                    getSearchNet(s.toString());
                    searchString = s.toString();
                }
    
                @Override
                public void afterTextChanged(Editable s) {
                }
            });
    
            return view;
        }
    

    将输入的关键字请求搜索内容。

    public void getSearchNet(String str){
            presenter.getSearch(searchUrl+str);
    }
    
    public void getSearch(String str) {
            Log.v("eee", "333==");
            Observable<SearchModel> observable = mModel.getSearch(str);
            observable.subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<SearchModel>() {
                        @Override
                        public void onSubscribe(Disposable d) {
    
                        }
    
                        @Override
                        public void onNext(SearchModel model) {
                            Log.v("eee", "222=="+model.getData().get(0).getWord());
                            searchModel = model;
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            Log.v("abbb", "222=="+e);
                        }
    
                        @Override
                        public void onComplete() {
                            Log.v("eee", "333==");
                            mView.getSearchModel(searchModel);
                        }
                    });
    }
    
    @Override
        public Observable<SearchModel> getSearch(String searchStr) {
            Observable<SearchModel> observable = RetrofitHelper.getInstance().getServer().getSearch(searchStr);
    }
    
    @Headers("Content-Type: application/json")
        @GET
        Observable<SearchModel> getSearch(@Url String url);
    

    请求的url是https://m.ctrip.com/restapi/h5api/searchapp/search?source=mobileweb&action=autocomplete&contentType=json&keyword=
    加上输入的关键字。可以随便填个关键字,用工具生成SearchModel。
    请求结果传回SearchPageActivity。

    @Override
        public void getSearchModel(SearchModel searchModel) {
            searchAdapter.getData(searchModel,searchString);
    }
    

    创建SearchAdapter,以及recycleview每个item的search_item.xml。

    public class SearchAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    
        List<SearchModel.Data> datas = new ArrayList();
        String keyWord;
        Activity context;
        String[] TYPES = {
                "channelgroup",
                "gs",
                "plane",
                "train",
                "cruise",
                "district",
                "food",
                "hotel",
                "huodong",
                "shop",
                "sight",
                "ticket",
                "travelgroup"
        };
        int[] DrawableResTYPES = {
                R.drawable.type_channelgroup,
                R.drawable.type_channelgs,
                R.drawable.type_channelplane,
                R.drawable.type_channeltrain,
                R.drawable.type_cruise,
                R.drawable.type_district,
                R.drawable.type_food,
                R.drawable.type_hotel,
                R.drawable.type_huodong,
                R.drawable.type_shop,
                R.drawable.type_sight,
                R.drawable.type_ticket,
                R.drawable.type_travelgroup,
    
        };
    
        public SearchAdapter(Activity context) {
            this.context = context;
        }
    
    
        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            return new SearchItemViewHolder(LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.search_item, parent, false));
        }
    
        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
            if (holder instanceof SearchItemViewHolder) {
                ((SearchItemViewHolder) holder).searchImage.setImageResource(imageType(datas.get(position).getType()));
                ((SearchItemViewHolder) holder).searchItem.setText(
                        KeyWordUtil.matcherSearchTitle(Color.GREEN, datas.get(position).getWord(), keyWord));
                Log.v("pe", "==" + datas.get(position).getPrice());
                if (datas.get(position).getPrice() == null) {
                    ((SearchItemViewHolder) holder).searchSubItem.setVisibility(View.GONE);
                } else {
                    ((SearchItemViewHolder) holder).searchSubItem.setText("¥" + datas.get(position).getPrice());
                }
                final String webViewUrl = datas.get(position).getUrl();
                ((SearchItemViewHolder) holder).searchLayout.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        intoWebView(webViewUrl);
                    }
                });
            }
        }
    
        public int imageType(String type) {
            if (type == null) {
                return R.drawable.type_channeltrain;
            }
            int path = 0;
            for (int a = 0; a < TYPES.length; a++) {
                if (type.contains(TYPES[a])) {
                    path = a;
                }
            }
            return DrawableResTYPES[path];
        }
    
        public void intoWebView(String url) {
            Intent startIntent = new Intent(context, WebViewActivity.class);
            startIntent.putExtra(ConstantsUtil.LOCAL_URL, url);
            context.startActivity(startIntent);
        }
    
        @Override
        public int getItemCount() {
            return datas.size();
        }
    
        public class SearchItemViewHolder extends RecyclerView.ViewHolder {
            LinearLayout searchLayout;
            ImageView searchImage;
            TextView searchItem;
            TextView searchSubItem;
    
            public SearchItemViewHolder(@NonNull View itemView) {
                super(itemView);
                searchLayout = itemView.findViewById(R.id.search_item_layout);
                searchImage = itemView.findViewById(R.id.search_image);
                searchItem = itemView.findViewById(R.id.search_text);
                searchSubItem = itemView.findViewById(R.id.search_sub_text);
            }
        }
    
        public void getData(SearchModel searchModel, String searchWord) {
            datas = searchModel.getData();
            keyWord = searchWord;
            notifyDataSetChanged();
        }
    
    
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/search_item_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:orientation="horizontal">
    
        <ImageView
            android:layout_gravity="center_vertical"
            android:id="@+id/search_image"
            android:padding="1dp"
            android:layout_width="26dp"
            android:layout_height="26dp" />
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <TextView
                android:id="@+id/search_text"
                android:layout_width="300dp"
                android:layout_height="wrap_content"
                android:maxLines="1"
                android:ellipsize="end"
                android:text="ff"
                android:textSize="16dp" />
    
            <TextView
                android:id="@+id/search_sub_text"
                android:layout_width="300dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dp"
                android:maxLines="1"
                android:textColor="#FFA500"
                android:ellipsize="end"
                android:text="ff"
                android:textSize="16dp" />
        </LinearLayout>
    
    </LinearLayout>
    

    需要注意的就是SearchAdapter里面,将搜索的关键字高亮了,具体操作是:
    创建一个工具类KeyWordUtil:

    /**
     * 文字变色工具类
     */
    public class KeyWordUtil {
    
        /**
         * 关键字高亮变色
         *
         * @param color   变化的色值
         * @param text    文字
         * @param keyword 文字中的关键字
         * @return 结果SpannableString
         */
        public static SpannableString matcherSearchTitle(int color, String text, String keyword) {
            Log.v("gg","text=="+text+"=="+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()) {
                        Log.v("gg","2222");
                        int start = m.start();
                        int end = m.end();
                        s.setSpan(new ForegroundColorSpan(color), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                } catch (Exception e) {
                }
            }
            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;
        }
    }
    

    将整个string和关键字,以及颜色传过去就好。

    KeyWordUtil.matcherSearchTitle(Color.GREEN, datas.get(position).getWord(), keyWord))
    

    注意这个颜色,需要用Color.xx,用R.color.xx的无效。
    具体代码如下:
    https://github.com/doudousang/edittext_recyclerview.git
    参考代码:
    Android搜索关键字高亮显示
    SpannableString详细解析

    相关文章

      网友评论

          本文标题:edittext+recycleview搜索功能

          本文链接:https://www.haomeiwen.com/subject/yovvwctx.html