順便看看,Android中過濾器是怎麼實現的?
註釋中提到,Filter通常經過繼承Filterable實現java
這是SimpleAdapter出現的一個過濾首字母item的一個過濾器android
private class SimpleFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence prefix) { FilterResults results = new FilterResults(); if (mUnfilteredData == null) { mUnfilteredData = new ArrayList<Map<String, ?>>(mData); } if (prefix == null || prefix.length() == 0) { ArrayList<Map<String, ?>> list = mUnfilteredData; results.values = list; results.count = list.size(); } else { String prefixString = prefix.toString().toLowerCase(); ArrayList<Map<String, ?>> unfilteredValues = mUnfilteredData; int count = unfilteredValues.size(); ArrayList<Map<String, ?>> newValues = new ArrayList<Map<String, ?>>(count); for (int i = 0; i < count; i++) { Map<String, ?> h = unfilteredValues.get(i); if (h != null) { int len = mTo.length; for (int j = 0; j < len; j++) { String str = (String) h.get(mFrom[j]); String[] words = str.split(" "); int wordCount = words.length; for (int k = 0; k < wordCount; k++) { String word = words[k]; if (word.toLowerCase().startsWith(prefixString)) { newValues.add(h); break; } } } } } results.values = newValues; results.count = newValues.size(); } return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { //noinspection unchecked mData = (List<Map<String, ?>>) results.values; if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } }
經過performFiltering
處理Result和publishResults
返回數據進行刷新。異步
抽象類Filter中filter開啓了對於數據的異步過濾操做。
尋找一下調用,發現AbsListView和AutoCompleteTextView 都有調用:
Abs中:ide
// 判斷類型 if (mAdapter instanceof Filterable) { Filter f = ((Filterable) mAdapter).getFilter(); // Filter should not be null when we reach this part if (f != null) { f.filter(s, this); } else { throw new IllegalStateException("You cannot call onTextChanged with a non " + "filterable adapter"); } }
Auto中:oop
protected void performFiltering(CharSequence text, int keyCode) { mFilter.filter(text, this); }
filter的調用經過一個限制詞和接口,接口判斷完成百分比。post
filter:ui
public final void filter(CharSequence constraint, FilterListener listener) { // 鎖 synchronized (mLock) { if (mThreadHandler == null) { // 開一個線程進行 這個線程自帶Looper HandlerThread thread = new HandlerThread( THREAD_NAME, android.os.Process.THREAD_PRIORITY_BACKGROUND); thread.start(); mThreadHandler = new RequestHandler(thread.getLooper()); } final long delay = (mDelayer == null) ? 0 : mDelayer.getPostingDelay(constraint); // 回收池拿一個msg Message message = mThreadHandler.obtainMessage(FILTER_TOKEN); // 包含了過濾的一切信息的對象 RequestArguments args = new RequestArguments(); // make sure we use an immutable copy of the constraint, so that // it doesn't change while the filter operation is in progress args.constraint = constraint != null ? constraint.toString() : null; args.listener = listener; message.obj = args; // 移除了以前未處理的消息 mThreadHandler.removeMessages(FILTER_TOKEN); mThreadHandler.removeMessages(FINISH_TOKEN); mThreadHandler.sendMessageDelayed(message, delay); } }
處理request的handler:this
private class RequestHandler extends Handler { public RequestHandler(Looper looper) { super(looper); } /** * <p>Handles filtering requests by calling * {@link Filter#performFiltering} and then sending a message * with the results to the results handler.</p> * * @param msg the filtering request */ public void handleMessage(Message msg) { int what = msg.what; Message message; switch (what) { case FILTER_TOKEN: RequestArguments args = (RequestArguments) msg.obj; try { // 處理過程 args.results = performFiltering(args.constraint); } catch (Exception e) { args.results = new FilterResults(); Log.w(LOG_TAG, "An exception occured during performFiltering()!", e); } finally { // 返回值 message = mResultHandler.obtainMessage(what); message.obj = args; message.sendToTarget(); } // 結束調用 synchronized (mLock) { if (mThreadHandler != null) { Message finishMessage = mThreadHandler.obtainMessage(FINISH_TOKEN); mThreadHandler.sendMessageDelayed(finishMessage, 3000); } } break; case FINISH_TOKEN: synchronized (mLock) { if (mThreadHandler != null) { mThreadHandler.getLooper().quit(); mThreadHandler = null; } } break; } } }
處理結果的Handler:線程
private class ResultsHandler extends Handler { /** * <p>Messages received from the request handler are processed in the * UI thread. The processing involves calling * {@link Filter#publishResults(CharSequence, * android.widget.Filter.FilterResults)} * to post the results back in the UI and then notifying the listener, * if any.</p> * * @param msg the filtering results */ @Override public void handleMessage(Message msg) { RequestArguments args = (RequestArguments) msg.obj; // 返回數據 publishResults(args.constraint, args.results); if (args.listener != null) { int count = args.results != null ? args.results.count : -1; args.listener.onFilterComplete(count); } } }