登录 立即注册
安币:

Android实现ListView过滤功能之继承BaseAdapter进阶版 [复制链接]

2016-8-1 02:42
zml_2015 阅读:15404 评论:7 赞:0
Tag:  ListViewsetTextFilter

Android实现ListView过滤功能之继承BaseAdapter进阶版

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

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

接下来直接上代码了 * 首先是布局文件

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.               android:layout_width="match_parent" 
  4.               android:layout_height="match_parent" 
  5.               android:background="@color/white" 
  6.               android:orientation="vertical" 
  7.     > 
  8.  
  9.     <LinearLayout 
  10.         android:id="@+id/search_top_layout" 
  11.         android:layout_width="match_parent" 
  12.         android:layout_height="wrap_content" 
  13.         android:layout_alignParentTop="true" 
  14.         android:background="@color/blue_title_bg" 
  15.         android:gravity="center_vertical" 
  16.         android:orientation="horizontal" > 
  17.  
  18.  
  19.         <com.zml.collrec.view.AutoClearEditText 
  20.             android:id="@+id/search_edit" 
  21.             android:layout_width="0dp" 
  22.             android:layout_height="wrap_content" 
  23.             android:layout_margin="5dp" 
  24.             android:layout_weight="1" 
  25.             android:background="@drawable/search_box" 
  26.             android:drawableRight="@drawable/app_icon_voice" 
  27.             android:focusable="true" 
  28.             android:hint="搜索" 
  29.             android:padding="6dp" 
  30.             android:singleLine="true" 
  31.             android:textColor="@color/black" 
  32.             android:textSize="@dimen/micro_text_size" /> 
  33.  
  34.         <ImageButton 
  35.             android:id="@+id/search_button" 
  36.             android:layout_width="wrap_content" 
  37.             android:layout_height="wrap_content" 
  38.             android:layout_margin="5dp" 
  39.             android:background="#035AB2" 
  40.             android:paddingLeft="10dp" 
  41.             android:paddingRight="10dp" 
  42.             android:src="@mipmap/android_search_icon" /> 
  43.     </LinearLayout> 
  44.  
  45.     <ListView 
  46.         android:id="@+id/search_list" 
  47.         android:layout_width="match_parent" 
  48.         android:layout_height="match_parent" 
  49.         android:layout_below="@id/search_top_layout" 
  50.         android:divider="@null" 
  51.         android:dividerHeight="1dp" 
  52.         android:listSelector="@null" 
  53.         android:scrollbars="none" 
  54.          /> 
  55.  
  56.     </LinearLayout>

视图布局就是  

SearchFragment.java

  1. /** 
  2.  * @author郑明亮    @email 1072307340@qq.com 
  3.  * @Time:2016/8/1 1:35 
  4.  * @version 1.0 
  5.  * TODO 
  6.  */public class SearchFragment extends Fragment implements AdapterView.OnItemClickListener, View.OnClickListener { 
  7.  
  8.     // TODO: Rename parameter arguments, choose names that match 
  9.     // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER 
  10.     private static final String ARG_PARAM1 = "param1"
  11.     private static final String ARG_PARAM2 = "param2"
  12.  
  13.     List<Recomend>data = null
  14.     // TODO: Rename and change types of parameters 
  15.     private String mParam1; 
  16.     private String mParam2; 
  17.     RecomendAdapter adapter = null
  18.  
  19.     private OnFragmentInteractionListener mListener; 
  20.  
  21.     AutoClearEditText et_search;//我自定义的EditText 
  22.     ImageButton ib_search; 
  23.     ListView search_list; 
  24.  
  25.  
  26.  
  27.     /** 
  28.      * Use this factory method to create a new instance of 
  29.      * this fragment using the provided parameters. 
  30.      * 
  31.      * @param param1 Parameter 1. 
  32.      * @param param2 Parameter 2. 
  33.      * @return A new instance of fragment SearchFragment. 
  34.      */ 
  35.     // TODO: Rename and change types and number of parameters 
  36.     public static SearchFragment newInstance(String param1, String param2) { 
  37.         SearchFragment fragment = new SearchFragment(); 
  38.         Bundle args = new Bundle(); 
  39.         args.putString(ARG_PARAM1, param1); 
  40.         args.putString(ARG_PARAM2, param2); 
  41.         fragment.setArguments(args); 
  42.         return fragment; 
  43.     } 
  44.  
  45.     @Override 
  46.     public void onCreate(Bundle savedInstanceState) { 
  47.         super.onCreate(savedInstanceState); 
  48.         if (getArguments() != null) { 
  49.             mParam1 = getArguments().getString(ARG_PARAM1); 
  50.             mParam2 = getArguments().getString(ARG_PARAM2); 
  51.         } 
  52.     } 
  53.  
  54.     @Override 
  55.     public View onCreateView(LayoutInflater inflater, ViewGroup container, 
  56.                              Bundle savedInstanceState) { 
  57.         View view = inflater.inflate(R.layout.fragment_search, container, false); 
  58.  
  59.         initView(view); 
  60.         //暂时模拟填充数据 
  61.         initData(); 
  62.         return view; 
  63.     } 
  64.  
  65.     private void initView(View view) { 
  66.         ib_search = (ImageButton) view.findViewById(R.id.search_button); 
  67.         et_search = (AutoClearEditText) view.findViewById(R.id.search_edit); 
  68.         search_list = (ListView) view.findViewById(R.id.search_list); 
  69.         search_list.setTextFilterEnabled(true); // 开启过滤功能 
  70.         ib_search.setOnClickListener(this); 
  71.         //为EditText(搜素框)设置一个TextWatcher来监视输入的动作 
  72.         et_search.addTextChangedListener(new TextWatcher() { 
  73.             @Override 
  74.             public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 
  75.  
  76.             } 
  77.  
  78.             @Override 
  79.             public void onTextChanged(CharSequence charSequence, int start, int before, int count) { 
  80.                 if (TextUtils.isEmpty(charSequence.toString().trim())) 
  81.                     search_list.clearTextFilter();//搜索文本为空时,清除ListView的过滤 
  82.                 else 
  83.                 search_list.setFilterText(charSequence.toString().trim());//设置过滤关键字 
  84.             } 
  85.  
  86.             @Override 
  87.             public void afterTextChanged(Editable editable) { 
  88.  
  89.             } 
  90.         }); 
  91.  
  92.     } 
  93.  
  94.     private void initData(){ 
  95.         data = new ArrayList<>(); 
  96.         data.add(new Recomend("应用推荐","忙碌一天的你,怎么能没有一款好玩的游戏来放松一下呢")); 
  97.         data.add(new Recomend("好书推荐","读过一本好书,像交了一个益友。——臧克家")); 
  98.         data.add(new Recomend("养生推荐","三天不吃青,兩眼冒金星。寧可食無肉,不可飯無湯。吃面多喝湯,免得開藥方")); 
  99.         data.add(new Recomend("资讯推荐","风声雨声读书声,声声入耳;家事国事天下事,事事关心,快来看看吧")); 
  100.         data.add(new Recomend("更多推荐","吃喝玩乐学一应俱全,快来看看吧")); 
  101.         data.add(new Recomend("更多推荐","吃喝玩乐学一应俱全,快来看看吧")); 
  102.         data.add(new Recomend("更多推荐","吃喝玩乐学一应俱全,快来看看吧")); 
  103.         data.add(new Recomend("更多推荐","吃喝玩乐学一应俱全,快来看看吧")); 
  104.         adapter = new RecomendAdapter(getActivity(),data); 
  105.         search_list.setAdapter(adapter); 
  106.         search_list.setOnItemClickListener(this); 
  107.     } 
  108.  
  109.     @Override 
  110.     public void onAttach(Context context) { 
  111.         super.onAttach(context); 
  112.     } 
  113.  
  114.     @Override 
  115.     public void onDetach() { 
  116.         super.onDetach(); 
  117.     } 
  118.  
  119.     @Override 
  120.     public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 
  121.         ScreenUtils.showToast(data.get(i).getTitle()); 
  122.     } 
  123.  
  124.     @Override 
  125.     public void onClick(View view) { 
  126.         switch (view.getId()){ 
  127.             case R.id.search_button: 
  128.                 String search = et_search.getText().toString().trim(); 
  129.                 if (TextUtils.isEmpty(search)){ 
  130.                     search_list.clearTextFilter();//搜索文本为空时,过滤设置 
  131.                 }else { 
  132. //                    search_list.clearTextFilter(); 
  133.                     search_list.setFilterText(search);//设置过滤关键字 
  134.                 } 
  135.  
  136.  
  137.                 break
  138.             default
  139.                 break
  140.         } 
  141.     } 
  142.  
  143. }

我在注释中已经注明了,需要注意的地方就是一定要先打开过滤功能search_list.setTextFilterEnabled(true) * 接下来是适配器的代码,关键代码;

  1. /** 
  2.  * @author 郑明亮   @email 1072307340@qq.com 
  3.  * @version 1.0 
  4.  * @time 2016/7/29 18:28 
  5.  * TODO 
  6.  */ 
  7. public class RecomendAdapter extends BaseAdapter implements Filterable{ 
  8.     Context context; 
  9.     List<Recomend> data; //这个数据是会改变的,所以要有个变量来备份一下原始数据 
  10.     List<Recomend> backData;//用来备份原始数据 
  11.     MyFilter mFilter ; 
  12.  
  13.     public RecomendAdapter(Context context, List<Recomend> data) { 
  14.         this.context = context; 
  15.         this.data = data; 
  16.         backData = data; 
  17.     } 
  18.  
  19.     @Override 
  20.     public int getCount() { 
  21.         return data.size(); 
  22.     } 
  23.  
  24.     @Override 
  25.     public Object getItem(int i) { 
  26.         return null
  27.     } 
  28.  
  29.     @Override 
  30.     public long getItemId(int i) { 
  31.         return 0
  32.     } 
  33.  
  34.     @Override 
  35.     public View getView(int i, View view, ViewGroup viewGroup) { 
  36.  
  37.         if (view ==null){ 
  38.             view = LayoutInflater.from(context).inflate(R.layout.fragment_recomend_item,null); 
  39.        } 
  40.         TextView tv_title = ViewHolder.get(view,R.id.tv_recomend_title); 
  41.         TextView tv_desc = ViewHolder.get(view,R.id.tv_recomend_desc); 
  42.         ImageView img = ViewHolder.get(view,R.id.iv_recomend_img); 
  43.         tv_title.setText(data.get(i).getTitle()); 
  44.         tv_desc.setText(data.get(i).getDesc()); 
  45.         Glide.with(context).load(R.drawable.default_head_icon).asBitmap().centerCrop().placeholder(R.mipmap.ic_launcher).into(img); 
  46.         return view; 
  47.     } 
  48.     //当ListView调用setTextFilter()方法的时候,便会调用该方法 
  49.     @Override 
  50.     public Filter getFilter() { 
  51.         if (mFilter ==null){ 
  52.             mFilter = new MyFilter(); 
  53.         } 
  54.         return mFilter; 
  55.     } 
  56.     //我们需要定义一个过滤器的类来定义过滤规则 
  57.      class MyFilter extends Filter{ 
  58.      //我们在performFiltering(CharSequence charSequence)这个方法中定义过滤规则 
  59.         @Override 
  60.         protected FilterResults performFiltering(CharSequence charSequence) { 
  61.             FilterResults result = new FilterResults(); 
  62.             List<Recomend> list ; 
  63.               if (TextUtils.isEmpty(charSequence)){//当过滤的关键字为空的时候,我们则显示所有的数据 
  64.                 list  = backData; 
  65.             }else {//否则把符合条件的数据对象添加到集合中 
  66.                 list = new ArrayList<>(); 
  67.                 for (Recomend recomend:backData){ 
  68.                     if (recomend.getTitle().contains(charSequence)||recomend.getDesc().contains(charSequence)){ 
  69.                         LogUtil.d("performFiltering:"+recomend.toString()); 
  70.                         list.add(recomend); 
  71.                     } 
  72.  
  73.                 } 
  74.             } 
  75.             result.values = list; //将得到的集合保存到FilterResults的value变量中 
  76.             result.count = list.size();//将集合的大小保存到FilterResults的count变量中 
  77.  
  78.             return result; 
  79.         } 
  80.     //在publishResults方法中告诉适配器更新界面 
  81.         @Override 
  82.         protected void publishResults(CharSequence charSequence, FilterResults filterResults) { 
  83.             data = (List<Recomend>)filterResults.values; 
  84.             LogUtil.d("publishResults:"+filterResults.count); 
  85.             if (filterResults.count>0){ 
  86.                 notifyDataSetChanged();//通知数据发生了改变 
  87.                 LogUtil.d("publishResults:notifyDataSetChanged"); 
  88.             }else { 
  89.                 notifyDataSetInvalidated();//通知数据失效 
  90.                 LogUtil.d("publishResults:notifyDataSetInvalidated"); 
  91.             } 
  92.         } 
  93.     } 
  94. }

有什么疑问的地方可以留言哦~

分享到:
我来说两句
facelist
您需要登录后才可以评论 登录 | 立即注册
所有评论(7)
zml_2015 2016-8-1 02:43
终于支持代码高亮了……如果能直接支持MarkDown的语法就好了
回复
MrlLee 2016-8-1 09:44
zml_2015: 终于支持代码高亮了……如果能直接支持MarkDown的语法就好了
这个会继续优化的
回复
zml_2015 2016-8-1 12:08
好嘞
回复
Cristina 2016-8-2 11:01
http://www.apkbus.com/thread-266731-1-1.html?_dsign=86e1db1f
可以回帖参加我是人气王的活动啦~
回复
zml_2015 2016-8-2 15:35
      
回复
芳心wei爱 2016-8-9 09:30
   ,这个好,正好项目中可以用到的。
回复
zml_2015 2016-8-9 12:29
芳心wei爱:    ,这个好,正好项目中可以用到的。
可以
回复

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条

下载安卓巴士客户端

全国最大的安卓开发者社区

广告投放| 下载客户端|申请友链|手机版|站点统计|安卓巴士 ( 粤ICP备15117877号 )

返回顶部