diff options
author | Patrick Dubroy <dubroy@google.com> | 2011-05-04 16:19:22 -0700 |
---|---|---|
committer | Patrick Dubroy <dubroy@google.com> | 2011-05-05 14:49:20 -0700 |
commit | e0a799a2ac1ca78e30fbac9e4e12a063425c08d3 (patch) | |
tree | 2c9b15f937b7c3b3db2bba4cf3df5a54838bbe69 | |
parent | a0449f03eb12462189f7a75f55e4751e1e2bcbcd (diff) | |
download | frameworks_base-e0a799a2ac1ca78e30fbac9e4e12a063425c08d3.zip frameworks_base-e0a799a2ac1ca78e30fbac9e4e12a063425c08d3.tar.gz frameworks_base-e0a799a2ac1ca78e30fbac9e4e12a063425c08d3.tar.bz2 |
Only delay pressed feedback for Views inside a scrolling parent
Add a method on ViewGroup to determine whether it supports scrolling.
This allows us to show the pressed feedback immediately in many cases,
improving responsiveness of buttons, etc.
This patch also lengthens the timeout in order to reduce flashes
when the user is scrolling.
Change-Id: Ieb91ae7a1f8e8f7e87448f2a730381a53947996f
-rw-r--r-- | api/current.txt | 1 | ||||
-rw-r--r-- | core/java/android/view/View.java | 55 | ||||
-rw-r--r-- | core/java/android/view/ViewConfiguration.java | 2 | ||||
-rw-r--r-- | core/java/android/view/ViewGroup.java | 13 | ||||
-rw-r--r-- | core/java/android/webkit/WebView.java | 5 | ||||
-rw-r--r-- | core/java/android/widget/AbsoluteLayout.java | 5 | ||||
-rw-r--r-- | core/java/android/widget/FrameLayout.java | 5 | ||||
-rw-r--r-- | core/java/android/widget/LinearLayout.java | 5 | ||||
-rw-r--r-- | core/java/android/widget/RelativeLayout.java | 5 | ||||
-rw-r--r-- | core/java/android/widget/ScrollView.java | 5 | ||||
-rw-r--r-- | core/java/com/android/internal/widget/ActionBarContextView.java | 5 | ||||
-rw-r--r-- | core/java/com/android/internal/widget/ActionBarView.java | 5 |
12 files changed, 92 insertions, 19 deletions
diff --git a/api/current.txt b/api/current.txt index a98ffae..09881f0 100644 --- a/api/current.txt +++ b/api/current.txt @@ -21724,6 +21724,7 @@ package android.view { method public void setOnHierarchyChangeListener(android.view.ViewGroup.OnHierarchyChangeListener); method public void setPersistentDrawingCache(int); method protected void setStaticTransformationsEnabled(boolean); + method public boolean shouldDelayChildPressedState(); method public boolean showContextMenuForChild(android.view.View); method public android.view.ActionMode startActionModeForChild(android.view.View, android.view.ActionMode.Callback); method public void startLayoutAnimation(); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 5af2e56..a25aa0d 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5138,9 +5138,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) && (event.getRepeatCount() == 0)) { setPressed(true); - if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { - postCheckForLongClick(0); - } + checkForLongClick(0); return true; } break; @@ -5535,12 +5533,33 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility break; case MotionEvent.ACTION_DOWN: - if (mPendingCheckForTap == null) { - mPendingCheckForTap = new CheckForTap(); - } - mPrivateFlags |= PREPRESSED; mHasPerformedLongPress = false; - postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); + + // Walk up the hierarchy to determine if we're inside a scrolling container. + boolean isInScrollingContainer = false; + ViewParent p = getParent(); + while (p != null && p instanceof ViewGroup) { + if (((ViewGroup) p).shouldDelayChildPressedState()) { + isInScrollingContainer = true; + break; + } + p = p.getParent(); + } + + // For views inside a scrolling container, delay the pressed feedback for + // a short period in case this is a scroll. + if (isInScrollingContainer) { + mPrivateFlags |= PREPRESSED; + if (mPendingCheckForTap == null) { + mPendingCheckForTap = new CheckForTap(); + } + postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); + } else { + // Not inside a scrolling container, so show the feedback right away + mPrivateFlags |= PRESSED; + refreshDrawableState(); + checkForLongClick(0); + } break; case MotionEvent.ACTION_CANCEL: @@ -11846,15 +11865,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } } - private void postCheckForLongClick(int delayOffset) { - mHasPerformedLongPress = false; + private void checkForLongClick(int delayOffset) { + if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { + mHasPerformedLongPress = false; - if (mPendingCheckForLongPress == null) { - mPendingCheckForLongPress = new CheckForLongPress(); + if (mPendingCheckForLongPress == null) { + mPendingCheckForLongPress = new CheckForLongPress(); + } + mPendingCheckForLongPress.rememberWindowAttachCount(); + postDelayed(mPendingCheckForLongPress, + ViewConfiguration.getLongPressTimeout() - delayOffset); } - mPendingCheckForLongPress.rememberWindowAttachCount(); - postDelayed(mPendingCheckForLongPress, - ViewConfiguration.getLongPressTimeout() - delayOffset); } /** @@ -12166,9 +12187,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility mPrivateFlags &= ~PREPRESSED; mPrivateFlags |= PRESSED; refreshDrawableState(); - if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { - postCheckForLongClick(ViewConfiguration.getTapTimeout()); - } + checkForLongClick(ViewConfiguration.getTapTimeout()); } } diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 94eb429..36bb046 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -95,7 +95,7 @@ public class ViewConfiguration { * is a tap or a scroll. If the user does not move within this interval, it is * considered to be a tap. */ - private static final int TAP_TIMEOUT = 115; + private static final int TAP_TIMEOUT = 180; /** * Defines the duration in milliseconds we will wait to see if a touch event diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 1a84175..d87026b 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -4973,6 +4973,19 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } /** + * Return true if the pressed state should be delayed for children or descendants of this + * ViewGroup. Generally, this should be done for containers that can scroll, such as a List. + * This prevents the pressed state from appearing when the user is actually trying to scroll + * the content. + * + * The default implementation returns true for compatibility reasons. Subclasses that do + * not scroll should generally override this method and return false. + */ + public boolean shouldDelayChildPressedState() { + return true; + } + + /** * LayoutParams are used by views to tell their parents how they want to be * laid out. See * {@link android.R.styleable#ViewGroup_Layout ViewGroup Layout Attributes} diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index b5d0492..7703ec7 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -1193,6 +1193,11 @@ public class WebView extends AbsoluteLayout mHTML5VideoViewProxy = null ; } + @Override + public boolean shouldDelayChildPressedState() { + return true; + } + /** * Adds accessibility APIs to JavaScript. * diff --git a/core/java/android/widget/AbsoluteLayout.java b/core/java/android/widget/AbsoluteLayout.java index ac82af7..7df6aab 100644 --- a/core/java/android/widget/AbsoluteLayout.java +++ b/core/java/android/widget/AbsoluteLayout.java @@ -141,6 +141,11 @@ public class AbsoluteLayout extends ViewGroup { return new LayoutParams(p); } + @Override + public boolean shouldDelayChildPressedState() { + return false; + } + /** * Per-child layout information associated with AbsoluteLayout. * See diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java index 590a768..0659063 100644 --- a/core/java/android/widget/FrameLayout.java +++ b/core/java/android/widget/FrameLayout.java @@ -485,6 +485,11 @@ public class FrameLayout extends ViewGroup { return new FrameLayout.LayoutParams(getContext(), attrs); } + @Override + public boolean shouldDelayChildPressedState() { + return false; + } + /** * {@inheritDoc} */ diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java index dbe9288..ed913a4 100644 --- a/core/java/android/widget/LinearLayout.java +++ b/core/java/android/widget/LinearLayout.java @@ -201,6 +201,11 @@ public class LinearLayout extends ViewGroup { mShowDividers = showDividers; } + @Override + public boolean shouldDelayChildPressedState() { + return false; + } + /** * @return A flag set indicating how dividers should be shown around items. * @see #setShowDividers(int) diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index a47359f..9069283 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -186,6 +186,11 @@ public class RelativeLayout extends ViewGroup { a.recycle(); } + @Override + public boolean shouldDelayChildPressedState() { + return false; + } + /** * Defines which View is ignored when the gravity is applied. This setting has no * effect if the gravity is <code>Gravity.LEFT | Gravity.TOP</code>. diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index ade3a0a..27edb88 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -162,6 +162,11 @@ public class ScrollView extends FrameLayout { } @Override + public boolean shouldDelayChildPressedState() { + return true; + } + + @Override protected float getTopFadingEdgeStrength() { if (getChildCount() == 0) { return 0.0f; diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java index 70fb3b2..ccaa146 100644 --- a/core/java/com/android/internal/widget/ActionBarContextView.java +++ b/core/java/com/android/internal/widget/ActionBarContextView.java @@ -448,4 +448,9 @@ public class ActionBarContextView extends ViewGroup implements AnimatorListener @Override public void onAnimationRepeat(Animator animation) { } + + @Override + public boolean shouldDelayChildPressedState() { + return false; + } } diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index 0c13f7b..d035744 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -232,6 +232,11 @@ public class ActionBarView extends ViewGroup { mHomeLayout.setFocusable(true); } + @Override + public boolean shouldDelayChildPressedState() { + return false; + } + public void initProgress() { mProgressView = new ProgressBar(mContext, null, 0, mProgressStyle); mProgressView.setId(R.id.progress_horizontal); |