diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java index dc5e864af87ad..f2325d0207725 100644 --- a/core/java/android/app/SuggestionsAdapter.java +++ b/core/java/android/app/SuggestionsAdapter.java @@ -40,6 +40,7 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.ResourceCursorAdapter; import android.widget.TextView; +import android.widget.Filter; import java.io.FileNotFoundException; import java.io.IOException; @@ -90,6 +91,12 @@ class SuggestionsAdapter extends ResourceCursorAdapter { private final Runnable mStartSpinnerRunnable; private final Runnable mStopSpinnerRunnable; + /** + * The amount of time we delay in the filter when the user presses the delete key. + * @see Filter#setDelayer(android.widget.Filter.Delayer). + */ + private static final long DELETE_KEY_POST_DELAY = 500L; + public SuggestionsAdapter(Context context, SearchDialog searchDialog, SearchableInfo searchable, WeakHashMap outsideDrawablesCache, boolean globalSearchMode) { super(context, @@ -119,6 +126,18 @@ class SuggestionsAdapter extends ResourceCursorAdapter { mSearchDialog.setWorking(false); } }; + + // delay 500ms when deleting + getFilter().setDelayer(new Filter.Delayer() { + + private int mPreviousLength = 0; + + public long getPostingDelay(CharSequence constraint) { + long delay = constraint.length() < mPreviousLength ? DELETE_KEY_POST_DELAY : 0; + mPreviousLength = constraint.length(); + return delay; + } + }); } /** diff --git a/core/java/android/widget/Filter.java b/core/java/android/widget/Filter.java index bdecf6242832c..d901540273275 100644 --- a/core/java/android/widget/Filter.java +++ b/core/java/android/widget/Filter.java @@ -46,6 +46,8 @@ public abstract class Filter { private Handler mThreadHandler; private Handler mResultHandler; + private Delayer mDelayer; + private final Object mLock = new Object(); /** @@ -55,6 +57,20 @@ public abstract class Filter { mResultHandler = new ResultsHandler(); } + /** + * Provide an interface that decides how long to delay the message for a given query. Useful + * for heuristics such as posting a delay for the delete key to avoid doing any work while the + * user holds down the delete key. + * + * @param delayer The delayer. + * @hide + */ + public void setDelayer(Delayer delayer) { + synchronized (mLock) { + mDelayer = delayer; + } + } + /** *

Starts an asynchronous filtering operation. Calling this method * cancels all previous non-executed filtering requests and posts a new @@ -90,6 +106,8 @@ public abstract class Filter { thread.start(); mThreadHandler = new RequestHandler(thread.getLooper()); } + + final long delay = (mDelayer == null) ? 0 : mDelayer.getPostingDelay(constraint); Message message = mThreadHandler.obtainMessage(FILTER_TOKEN); @@ -102,7 +120,7 @@ public abstract class Filter { mThreadHandler.removeMessages(FILTER_TOKEN); mThreadHandler.removeMessages(FINISH_TOKEN); - mThreadHandler.sendMessage(message); + mThreadHandler.sendMessageDelayed(message, delay); } } @@ -289,4 +307,17 @@ public abstract class Filter { */ FilterResults results; } + + /** + * @hide + */ + public interface Delayer { + + /** + * @param constraint The constraint passed to {@link Filter#filter(CharSequence)} + * @return The delay that should be used for + * {@link Handler#sendMessageDelayed(android.os.Message, long)} + */ + long getPostingDelay(CharSequence constraint); + } }