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.}
有什么疑问的地方可以留言哦~