android基础讲解-ArrayFilter
转载请注明作者出处谢谢 :http://www.cnblogs.com/TS-Alex/p/4793391.html
今天看了一下ArrayList的过滤器ArrayFilter 在这里对过滤的机制进行一下总结
ArrayFilter是Filter的一个实现类同时也是ArrayList的内部类,其主要的功能是实现数据集的过滤
获取过滤器对象的方法
1 ArrayAdapter<String> aa=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new String[]{"1","2","3"});; 2 Filter filter= aa.getFilter();//
这里得到的filter对象的实际对象是ArrayFilter
源代码中ArrayFilter的实现代码如下
1 private class ArrayFilter extends Filter { 2 @Override 3 protected FilterResults performFiltering(CharSequence prefix) {//这个是实现过滤的具体方法在子类中实现 4 FilterResults results = new FilterResults(); 5 6 if (mOriginalValues == null) { 7 synchronized (mLock) { 8 mOriginalValues = new ArrayList<T>(mObjects); 9 } 10 } 11 12 if (prefix == null || prefix.length() == 0) {//prefix过滤字符串 如果当前输入的字符串为空则显示全部的数据 13 ArrayList<T> list; 14 synchronized (mLock) { 15 list = new ArrayList<T>(mOriginalValues);//使用已有的集合构建一个arraylist对象 16 } 17 results.values = list;//一个object对象 保存原始的集合 18 results.count = list.size();//一个int对象 19 } else { 20 String prefixString = prefix.toString().toLowerCase();//转换为小写 21 22 ArrayList<T> values;//保存原始数据集合 23 synchronized (mLock) { 24 values = new ArrayList<T>(mOriginalValues); 25 } 26 27 final int count = values.size();//原始数据的大小 28 final ArrayList<T> newValues = new ArrayList<T>();//保存新的数据集合 29 30 for (int i = 0; i < count; i++) { 31 final T value = values.get(i); 32 final String valueText = value.toString().toLowerCase(); 33 34 // First match against the whole, non-splitted value 35 if (valueText.startsWith(prefixString)) {//先查询所有以过滤字符串开头的字符 36 newValues.add(value);//将符合过滤要求的数据添加到新的数据集中 37 } else { 38 final String[] words = valueText.split(" "); 39 final int wordCount = words.length; 40 41 // Start at index 0, in case valueText starts with space(s) 42 for (int k = 0; k < wordCount; k++) { 43 if (words[k].startsWith(prefixString)) { 44 newValues.add(value); 45 break; 46 } 47 } 48 } 49 } 50 51 results.values = newValues; 52 results.count = newValues.size(); 53 } 54 55 return results; 56 } 57 //当过滤结束后调用的函数 58 @Override 59 protected void publishResults(CharSequence constraint, FilterResults results) { 60 //noinspection unchecked 61 mObjects = (List<T>) results.values; 62 if (results.count > 0) { 63 notifyDataSetChanged();//更新可见区 64 } else { 65 notifyDataSetInvalidated();//更新整个组件 66 } 67 } 68 }
如上述代码中所述红色字体的两个方法是抽象父类Filter的两个抽象方法的实现
performFiltering(String)方法是具体实现过滤的代码 实现怎么样的过滤算法在这个方法中实现 具体怎么调用的在下面说明
publishResults(CharSequence constraint, FilterResults results)方法是过滤完成后的回调函数,在过滤完成后会回调这个方法
下面具体说明Filter的内部调用机制
我们在实现过滤时调用的是Filter的filter(CharSequence constraint, FilterListener listener)函数
1 public final void filter(CharSequence constraint) { 2 filter(constraint, null); 3 }
在这里我们先看一下Filter的一些成员和内部类
private Handler mThreadHandler; private Handler mResultHandler;
mThreadHandler 它是 RequestHandler类的实例
RequestHandler是Filter的内部类
这个handler绑定了执行过滤的线程looper 这个handler用于向过滤线程发送消息主要的消息有两种
FILTER_TOKEN 消息 这个消息通知Filter类进行过滤操作并且删除之前在消息队列中的过滤消息和结束消息
FINISH_TOKEN:消息 下个消息是在每次发送一次过滤消息后会发送一个延时消息延时时间是3秒如果3秒内没有再次发送过滤消息就会销毁mThreadHandler 对象
1 private class RequestHandler extends Handler { 2 public RequestHandler(Looper looper) { 3 super(looper); 4 } 5 6 /** 7 * <p>Handles filtering requests by calling 8 * {@link Filter#performFiltering} and then sending a message 9 * with the results to the results handler.</p> 10 * 11 * @param msg the filtering request 12 */ 13 public void handleMessage(Message msg) { 14 int what = msg.what; 15 Message message; 16 switch (what) { 17 case FILTER_TOKEN: 18 RequestArguments args = (RequestArguments) msg.obj; 19 try { 20 args.results = performFiltering(args.constraint);//调用实现类中的方法进行过滤 返回一个过滤结果对象 这个对象包含一个数据集 21 } catch (Exception e) { 22 args.results = new FilterResults();//发生过滤异常创建一个空的过滤结果 空的数据集 23 Log.w(LOG_TAG, "An exception occured during performFiltering()!", e); 24 } finally { 25 message = mResultHandler.obtainMessage(what);//发送结果消息 26 message.obj = args; 27 message.sendToTarget(); 28 } 29 30 synchronized (mLock) { 31 if (mThreadHandler != null) { 32 Message finishMessage = mThreadHandler.obtainMessage(FINISH_TOKEN); 33 mThreadHandler.sendMessageDelayed(finishMessage, 3000);//发送延时消息 34 } 35 } 36 break; 37 case FINISH_TOKEN: 38 synchronized (mLock) { 39 if (mThreadHandler != null) {//销毁handler 40 mThreadHandler.getLooper().quit(); 41 mThreadHandler = null; 42 } 43 } 44 break; 45 } 46 } 47 }
mResultHandler 它是ResultsHandler类的实例
ResultsHandler是Filter的内部类
这个handler绑定了创建这个Filter对象的线程looper()一般是主线程 这个处理消息的函数主要用于处理最开始说的那个调用函数
1 private class ResultsHandler extends Handler { 2 @Override 3 public void handleMessage(Message msg) { 4 RequestArguments args = (RequestArguments) msg.obj; 5 6 publishResults(args.constraint, args.results);//实现方法在子类 7 if (args.listener != null) {//这个逻辑是如果传递了回调方法接口参数则调用这个接口方法 8 int count = args.results != null ? args.results.count : -1;//我暂时认为这里用于判断过滤是否成功 因为过滤发生异常会返回-1 9 args.listener.onFilterComplete(count); 10 } 11 } 12 }
今天先写到这里。