summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Dubroy <dubroy@google.com>2011-05-04 16:19:22 -0700
committerPatrick Dubroy <dubroy@google.com>2011-05-05 14:49:20 -0700
commite0a799a2ac1ca78e30fbac9e4e12a063425c08d3 (patch)
tree2c9b15f937b7c3b3db2bba4cf3df5a54838bbe69
parenta0449f03eb12462189f7a75f55e4751e1e2bcbcd (diff)
downloadframeworks_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.txt1
-rw-r--r--core/java/android/view/View.java55
-rw-r--r--core/java/android/view/ViewConfiguration.java2
-rw-r--r--core/java/android/view/ViewGroup.java13
-rw-r--r--core/java/android/webkit/WebView.java5
-rw-r--r--core/java/android/widget/AbsoluteLayout.java5
-rw-r--r--core/java/android/widget/FrameLayout.java5
-rw-r--r--core/java/android/widget/LinearLayout.java5
-rw-r--r--core/java/android/widget/RelativeLayout.java5
-rw-r--r--core/java/android/widget/ScrollView.java5
-rw-r--r--core/java/com/android/internal/widget/ActionBarContextView.java5
-rw-r--r--core/java/com/android/internal/widget/ActionBarView.java5
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);