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

  • 相关阅读:
    (转)搜索Maven仓库 获取 groupid artifactId
    idea自用快捷键(非常实用)
    (2)一起来看下使用mybatis框架的insert语句的源码执行流程吧
    (1)复习jdbc操作,编译mybatis源码,准备为你的简历加分吧
    关于CPU核心,线程,进程,并发,并行,及java线程之间的关系
    数组排序
    泛型类、泛型方法、类型通配符的使用
    数组的三种声明方式总结、多维数组的遍历、Arrays类的常用方法总结
    Java基本数据类型总结、类型转换、常量的声明规范,final关键字的用法
    JAVA基础语法——标识符、修饰符、关键字(个人整理总结)
  • 原文地址:https://www.cnblogs.com/wjhblogs/p/4832591.html
Copyright © 2011-2022 走看看