美文网首页Android
Android实现ListView过滤功能之继承BaseAdap

Android实现ListView过滤功能之继承BaseAdap

作者: 老子爱吃荷包蛋 | 来源:发表于2019-03-27 13:38 被阅读0次

    作者:zml_2015
    原文:https://blog.csdn.net/zml_2015/article/details/52082174

    实现ListView过滤功能最方便的便是使用ArrayAdapter,里面自带的getFilter()方法能很方便的实现此功能

    但是在实际的开发中,ArrayAdapter有的时候满足不了我们项目的各种需求,所以一般都是继承于BaseAdapter,然后继承BaseAdapter不能像ArrayAdapter那样直接通过ListView的setTextFilter()就对ListView进行简单的过滤,我们需要去手动实现一个Filterable接口,自定义过滤规则;
    效果图


    image.png image.png

    接下来直接上代码了

    • 首先是布局文件
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="@color/white"
                  android:orientation="vertical"
        >
    
        <LinearLayout
            android:id="@+id/search_top_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:background="@color/blue_title_bg"
            android:gravity="center_vertical"
            android:orientation="horizontal" >
    
    
            <com.zml.collrec.view.AutoClearEditText
                android:id="@+id/search_edit"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:layout_weight="1"
                android:background="@drawable/search_box"
                android:drawableRight="@drawable/app_icon_voice"
                android:focusable="true"
                android:hint="搜索"
                android:padding="6dp"
                android:singleLine="true"
                android:textColor="@color/black"
                android:textSize="@dimen/micro_text_size" />
    
            <ImageButton
                android:id="@+id/search_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:background="#035AB2"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:src="@mipmap/android_search_icon" />
        </LinearLayout>
    
        <ListView
            android:id="@+id/search_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/search_top_layout"
            android:divider="@null"
            android:dividerHeight="1dp"
            android:listSelector="@null"
            android:scrollbars="none"
             />
    
        </LinearLayout>
    

    布局视图


    image.png
     
    * SearchFragment.java
    
    /**
     * @author郑明亮    @email 1072307340@qq.com
     * @Time:2016/8/1 1:35
     * @version 1.0
     * TODO
     */public class SearchFragment extends Fragment implements AdapterView.OnItemClickListener, View.OnClickListener {
    
        // TODO: Rename parameter arguments, choose names that match
        // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
        private static final String ARG_PARAM1 = "param1";
        private static final String ARG_PARAM2 = "param2";
    
        List<Recomend>data = null;
        // TODO: Rename and change types of parameters
        private String mParam1;
        private String mParam2;
        RecomendAdapter adapter = null;
    
        private OnFragmentInteractionListener mListener;
    
        AutoClearEditText et_search;//我自定义的EditText
        ImageButton ib_search;
        ListView search_list;
    
    
    
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment SearchFragment.
         */
        // TODO: Rename and change types and number of parameters
        public static SearchFragment newInstance(String param1, String param2) {
            SearchFragment fragment = new SearchFragment();
            Bundle args = new Bundle();
            args.putString(ARG_PARAM1, param1);
            args.putString(ARG_PARAM2, param2);
            fragment.setArguments(args);
            return fragment;
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (getArguments() != null) {
                mParam1 = getArguments().getString(ARG_PARAM1);
                mParam2 = getArguments().getString(ARG_PARAM2);
            }
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_search, container, false);
    
            initView(view);
            //暂时模拟填充数据
            initData();
            return view;
        }
    
        private void initView(View view) {
            ib_search = (ImageButton) view.findViewById(R.id.search_button);
            et_search = (AutoClearEditText) view.findViewById(R.id.search_edit);
            search_list = (ListView) view.findViewById(R.id.search_list);
            search_list.setTextFilterEnabled(true); // 开启过滤功能
            ib_search.setOnClickListener(this);
            //为EditText(搜素框)设置一个TextWatcher来监视输入的动作
            et_search.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    
                }
    
                @Override
                public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
                    if (TextUtils.isEmpty(charSequence.toString().trim()))
                        search_list.clearTextFilter();//搜索文本为空时,清除ListView的过滤
                    else
                    search_list.setFilterText(charSequence.toString().trim());//设置过滤关键字
                }
    
                @Override
                public void afterTextChanged(Editable editable) {
    
                }
            });
    
        }
    
        private void initData(){
            data = new ArrayList<>();
            data.add(new Recomend("应用推荐","忙碌一天的你,怎么能没有一款好玩的游戏来放松一下呢"));
            data.add(new Recomend("好书推荐","读过一本好书,像交了一个益友。——臧克家"));
            data.add(new Recomend("养生推荐","三天不吃青,兩眼冒金星。寧可食無肉,不可飯無湯。吃面多喝湯,免得開藥方"));
            data.add(new Recomend("资讯推荐","风声雨声读书声,声声入耳;家事国事天下事,事事关心,快来看看吧"));
            data.add(new Recomend("更多推荐","吃喝玩乐学一应俱全,快来看看吧"));
            data.add(new Recomend("更多推荐","吃喝玩乐学一应俱全,快来看看吧"));
            data.add(new Recomend("更多推荐","吃喝玩乐学一应俱全,快来看看吧"));
            data.add(new Recomend("更多推荐","吃喝玩乐学一应俱全,快来看看吧"));
            adapter = new RecomendAdapter(getActivity(),data);
            search_list.setAdapter(adapter);
            search_list.setOnItemClickListener(this);
        }
    
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
        }
    
        @Override
        public void onDetach() {
            super.onDetach();
        }
    
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            ScreenUtils.showToast(data.get(i).getTitle());
        }
    
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.search_button:
                    String search = et_search.getText().toString().trim();
                    if (TextUtils.isEmpty(search)){
                        search_list.clearTextFilter();//搜索文本为空时,过滤设置
                    }else {
    //                    search_list.clearTextFilter();
                        search_list.setFilterText(search);//设置过滤关键字
                    }
    
    
                    break;
                default:
                    break;
            }
        }
    
    }
    

    我在注释中已经注明了,需要注意的地方就是一定要先打开过滤功能 search_list.setTextFilterEnabled(true)

    • 接下来是适配器的代码,关键代码;
    /**
     * @author 郑明亮   @email 1072307340@qq.com
     * @version 1.0
     * @time 2016/7/29 18:28
     * TODO
     */
    public class RecomendAdapter extends BaseAdapter implements Filterable{
        Context context;
        List<Recomend> data; //这个数据是会改变的,所以要有个变量来备份一下原始数据
        List<Recomend> backData;//用来备份原始数据
        MyFilter mFilter ;
    
        public RecomendAdapter(Context context, List<Recomend> data) {
            this.context = context;
            this.data = data;
            backData = data;
        }
    
        @Override
        public int getCount() {
            return data.size();
        }
    
        @Override
        public Object getItem(int i) {
            return null;
        }
    
        @Override
        public long getItemId(int i) {
            return 0;
        }
    
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
    
            if (view ==null){
                view = LayoutInflater.from(context).inflate(R.layout.fragment_recomend_item,null);
           }
            TextView tv_title = ViewHolder.get(view,R.id.tv_recomend_title);
            TextView tv_desc = ViewHolder.get(view,R.id.tv_recomend_desc);
            ImageView img = ViewHolder.get(view,R.id.iv_recomend_img);
            tv_title.setText(data.get(i).getTitle());
            tv_desc.setText(data.get(i).getDesc());
            Glide.with(context).load(R.drawable.default_head_icon).asBitmap().centerCrop().placeholder(R.mipmap.ic_launcher).into(img);
            return view;
        }
        //当ListView调用setTextFilter()方法的时候,便会调用该方法
        @Override
        public Filter getFilter() {
            if (mFilter ==null){
                mFilter = new MyFilter();
            }
            return mFilter;
        }
        //我们需要定义一个过滤器的类来定义过滤规则
         class MyFilter extends Filter{
         //我们在performFiltering(CharSequence charSequence)这个方法中定义过滤规则
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                FilterResults result = new FilterResults();
                List<Recomend> list ;
                  if (TextUtils.isEmpty(charSequence)){//当过滤的关键字为空的时候,我们则显示所有的数据
                    list  = backData;
                }else {//否则把符合条件的数据对象添加到集合中
                    list = new ArrayList<>();
                    for (Recomend recomend:backData){
                        if (recomend.getTitle().contains(charSequence)||recomend.getDesc().contains(charSequence)){
                            LogUtil.d("performFiltering:"+recomend.toString());
                            list.add(recomend);
                        }
    
                    }
                }
                result.values = list; //将得到的集合保存到FilterResults的value变量中
                result.count = list.size();//将集合的大小保存到FilterResults的count变量中
    
                return result;
            }
        //在publishResults方法中告诉适配器更新界面
            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                data = (List<Recomend>)filterResults.values;
                LogUtil.d("publishResults:"+filterResults.count);
                if (filterResults.count>0){
                    notifyDataSetChanged();//通知数据发生了改变
                    LogUtil.d("publishResults:notifyDataSetChanged");
                }else {
                    notifyDataSetInvalidated();//通知数据失效
                    LogUtil.d("publishResults:notifyDataSetInvalidated");
                }
            }
        }
    }
    

    最后用search_list.setFilterText(search);//设置过滤关键字 会出现如效果图出现的黑色的框
    可以使用adapter.getFilter().filter(s)就不会有那个框框了 。

    相关文章

      网友评论

        本文标题:Android实现ListView过滤功能之继承BaseAdap

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