zoukankan      html  css  js  c++  java
  • Android 自定义过滤搜索框 filterable

    简单的说就是ListView上面有一个SearchBox,然后searchbox里输入内容后对下面listview进行过滤。

    涉及的控件:ListView必须有,EditText用来自定义SearchBox

    大概就是这样:

     

     

    先看这个有图片的EditText,实现方法有两个,一是用相对布局RelativeLayout + ImageView + EditText。

    二是直接用EditText的一个属性DrawableLeft,简单的UI这个就可以实现了

    所以这个Activity的布局就很简单,可以用ListActivity实现:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity" >
    
        <EditText
            android:id="@+id/searchbox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:drawableLeft="@drawable/searchbox"
            android:hint="Search"
            android:drawablePadding="5dp"
            android:singleLine="true"
            android:ems="10" >
            <requestFocus />
        </EditText>
    
        
        <ListView 
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/searchbox">
        </ListView>
     
    </RelativeLayout>
    

    再说过滤功能:这个感觉不想搜索,就像是简单的过滤,如果涉及到去数据库取数据那个才是搜索了

    用到了Filterable接口,Filter类

    要让数据有过滤功能,我们需要在继承的BaseAdapter的基础上再实现Filterable接口的getFilter方法,同时在Adapter内部写一个继承Filter的内部类来完成过滤功能:

    private class ListAdapter extends BaseAdapter implements Filterable {
    
    		private List<Person> list;
    		
    		private Context context;
    		
    		private PersonFilter filter;
    		
    		public ListAdapter(List<Person> list, Context context) {
    			this.list = list;
    			this.context = context;
    		}
    
    		@Override
    		public int getCount() {
    			return list.size();
    		}
    
    		@Override
    		public Object getItem(int position) {
    			return list.get(position);
    		}
    
    		@Override
    		public long getItemId(int position) {
    			return position;
    		}
    
    		@Override
    		public View getView(int position, View convertView, ViewGroup parent) {
    			if (convertView == null) {
    				convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);
    			}
    			Person p = list.get(position);
    			TextView firstname = (TextView)convertView.findViewById(R.id.firstname);
    			TextView lastname = (TextView)convertView.findViewById(R.id.lastname);
    			TextView age = (TextView)convertView.findViewById(R.id.age);
    			
    			firstname.setText(p.firstname);
    			lastname.setText(p.lastname);
    			age.setText(p.age + "");
    			return convertView;
    		}
    
    		@Override
    		public Filter getFilter() {
    			if (filter == null) {
    				filter = new PersonFilter(list);
    			}
    			return filter;
    		}
    		
    		private class PersonFilter extends Filter {
    			
    			private List<Person> original;
    			
    			public PersonFilter(List<Person> list) {
    				this.original = list;
    			}
    
    			@Override
    			protected FilterResults performFiltering(CharSequence constraint) {
    				FilterResults results = new FilterResults();
    				if (constraint == null || constraint.length() == 0) {
    					results.values = original;
    					results.count = original.size();
    				} else {
    					List<Person> mList = new ArrayList<Person>();
    					for (Person p: original) {
    						if (p.firstname.toUpperCase().startsWith(constraint.toString().toUpperCase())
    							|| p.lastname.toUpperCase().startsWith(constraint.toString().toUpperCase())
    							|| new String(p.age + "").toUpperCase().startsWith(constraint.toString().toUpperCase())) {
    							mList.add(p);
    						}
    					}
    					results.values = mList;
    					results.count = mList.size();
    				}
    				return results;
    			}
    
    			@Override
    			protected void publishResults(CharSequence constraint,
    					FilterResults results) {
    				list = (List<Person>)results.values;
    				notifyDataSetChanged();
    			}
    			
    		}
    	}
    

     Filter类中的两个方法看名字就是知道一个是执行过滤的,一个刷新listview数据展现结果的。其中我采用了前缀匹配,就是用输入的字符串和ListView里的所有Person的各个属性的前缀做比较。也可以用更加复杂的匹配,例如正则表达式。

    关键在于EditText里的数据是如何传入的,要写一个TextWater,并且要让EditText注册一下这个监听器:

            private TextWatcher filterTextWatcher = new TextWatcher() {
    
    		@Override
    		public void afterTextChanged(Editable s) {
    
    		}
    
    		@Override
    		public void beforeTextChanged(CharSequence s, int start, int count,
    				int after) {
    
    		}
    
    		@Override
    		public void onTextChanged(CharSequence s, int start, int before,
    				int count) {
    			listAdapter.getFilter().filter(s); //这里传入数据就可以了
    		}
    
    	};
    

     以上关键代码。非关键代码是Person类以及List_Item的布局:

            private class Person {
    		public String firstname;
    		public String lastname;
    		public int age;
    		
    		public Person(String firtname, String lastname, int age) {
    			this.firstname = firtname;
    			this.lastname = lastname;
    			this.age = age;
    		}
    	}
    

     List_Item布局:

    <?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:orientation="horizontal" >
    
        <TextView
            android:id="@+id/firstname"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:text="Firstname" />
    
        <TextView
            android:id="@+id/lastname"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:text="Lastname" />
        
        <TextView
            android:id="@+id/age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:text="Age" />
    
    </LinearLayout>
    

    /home/wangjianhua/Desktop/1365932013_4825.jpg

  • 相关阅读:
    为什么需要Docker?
    一分钟学会《模板方法模式》
    2018再见|2019你好
    三分钟学会《门面模式》
    策略模式原来这么简单!
    外行人都能看得懂的机器学习,错过了血亏!
    我是如何将博客转成PDF的
    面试前必须知道的MySQL命令【explain】
    count(*)、count(1)和count(列名)的区别
    Linux shell去除字符串中所有空格
  • 原文地址:https://www.cnblogs.com/wjhblogs/p/4832591.html
Copyright © 2011-2022 走看看