轉載請註明做者出處謝謝 :http://www.cnblogs.com/TS-Alex/p/4793391.htmlhtml
今天看了一下ArrayList的過濾器ArrayFilter 在這裏對過濾的機制進行一下總結android
ArrayFilter是Filter的一個實現類同時也是ArrayList的內部類,其主要的功能是實現數據集的過濾算法
獲取過濾器對象的方法ide
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的實現代碼以下oop
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的一些成員和內部類ui
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 }
今天先寫到這裏。this