publicinterfaceFilterable { /** * <p>Returns a filter that can be used to constrain data with a filtering * pattern.</p> * * <p>This method is usually implemented by {@link android.widget.Adapter} * classes.</p> * * @return a filter used to constrain data */ Filter getFilter(); }
/** * <p>Starts an asynchronous filtering operation. Calling this method * cancels all previous non-executed filtering requests and posts a new * filtering request that will be executed later.</p> * * <p>Upon completion, the listener is notified.</p> * * @param constraint the constraint used to filter the data * @param listener a listener notified upon completion of the operation * * @see #filter(CharSequence) * @see #performFiltering(CharSequence) * @see #publishResults(CharSequence, android.widget.Filter.FilterResults) */ publicfinalvoidfilter(CharSequence constraint, FilterListener listener) { synchronized (mLock) { if (mThreadHandler == null) { HandlerThreadthread=newHandlerThread( THREAD_NAME, android.os.Process.THREAD_PRIORITY_BACKGROUND); thread.start(); mThreadHandler = newRequestHandler(thread.getLooper()); }
RequestArgumentsargs=newRequestArguments(); // 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;
/** * Runs a query with the specified constraint. This query is requested * by the filter attached to this adapter. * * The query is provided by a * {@link android.widget.FilterQueryProvider}. * If no provider is specified, the current cursor is not filtered and returned. * * After this method returns the resulting cursor is passed to {@link #changeCursor(Cursor)} * and the previous cursor is closed. * * This method is always executed on a background thread, not on the * application's main thread (or UI thread.) * * Contract: when constraint is null or empty, the original results, * prior to any filtering, must be returned. * * @param constraint the constraint with which the query must be filtered * * @return a Cursor representing the results of the new query * * @see #getFilter() * @see #getFilterQueryProvider() * @see #setFilterQueryProvider(android.widget.FilterQueryProvider) */ public Cursor runQueryOnBackgroundThread(CharSequence constraint) { if (mFilterQueryProvider != null) { return mFilterQueryProvider.runQuery(constraint); }
/** * <p>Handles the results of a filtering operation. The results are * handled in the UI thread.</p> */ privateclassResultsHandlerextendsHandler { /** * <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 publicvoidhandleMessage(Message msg) { RequestArgumentsargs= (RequestArguments) msg.obj;
/** * Change the underlying cursor to a new cursor. If there is an existing cursor it will be * closed. * * @param cursor The new cursor to be used */ publicvoidchangeCursor(Cursor cursor) { Cursorold= swapCursor(cursor); if (old != null) { old.close(); } }
/** * Swap in a new Cursor, returning the old Cursor. Unlike * {@link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em> * closed. * * @param newCursor The new cursor to be used. * @return Returns the previously set Cursor, or null if there wasa not one. * If the given new Cursor is the same instance is the previously set * Cursor, null is also returned. */ public Cursor swapCursor(Cursor newCursor) { if (newCursor == mCursor) { returnnull; } CursoroldCursor= mCursor; if (oldCursor != null) { if (mChangeObserver != null) oldCursor.unregisterContentObserver(mChangeObserver); if (mDataSetObserver != null) oldCursor.unregisterDataSetObserver(mDataSetObserver); } mCursor = newCursor; if (newCursor != null) { if (mChangeObserver != null) newCursor.registerContentObserver(mChangeObserver); if (mDataSetObserver != null) newCursor.registerDataSetObserver(mDataSetObserver); mRowIDColumn = newCursor.getColumnIndexOrThrow("_id"); mDataValid = true; // notify the observers about the new cursor notifyDataSetChanged(); } else { mRowIDColumn = -1; mDataValid = false; // notify the observers about the lack of a data set notifyDataSetInvalidated(); } return oldCursor; }