Fix touch handling in DragLayout.
Fixes: 33104074
-Only accept drags on HistoryFrame when isOpen()
-requestDisallowInterceptTouchEvent() in CalculatorResult to prevent
DragLayout from scrolling when a CalculatorResult is the target
Change-Id: If0dfbccc2fc05a90383a03cf397e6becd4496554
diff --git a/src/com/android/calculator2/Calculator.java b/src/com/android/calculator2/Calculator.java
index 8452566..156d1b5 100644
--- a/src/com/android/calculator2/Calculator.java
+++ b/src/com/android/calculator2/Calculator.java
@@ -241,13 +241,11 @@
}
@Override
- public boolean allowDrag(MotionEvent event) {
- return isViewTarget(mHistoryFrame, event) || isViewTarget(mDisplayView, event);
- }
-
- @Override
public boolean shouldInterceptTouchEvent(MotionEvent event) {
- return isViewTarget(mHistoryFrame, event) || isViewTarget(mDisplayView, event);
+ if (!mDragLayout.isOpen()) {
+ return isViewTarget(mDisplayView, event);
+ }
+ return true;
}
@Override
diff --git a/src/com/android/calculator2/CalculatorResult.java b/src/com/android/calculator2/CalculatorResult.java
index 83758b8..e33117f 100644
--- a/src/com/android/calculator2/CalculatorResult.java
+++ b/src/com/android/calculator2/CalculatorResult.java
@@ -43,6 +43,7 @@
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewConfiguration;
import android.widget.OverScroller;
import android.widget.Toast;
@@ -153,6 +154,10 @@
private ActionMode.Callback mCopyActionModeCallback;
private ContextMenu mContextMenu;
+ // Used to determine whether a touch event should be intercepted.
+ private float mInitialDownX;
+ private float mInitialDownY;
+
// The user requested that the result currently being evaluated should be stored to "memory".
private boolean mStoreToMemoryRequested = false;
@@ -169,8 +174,8 @@
return true;
}
@Override
- public boolean onFling(MotionEvent e1, MotionEvent e2,
- float velocityX, float velocityY) {
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
+ float velocityY) {
if (!mScroller.isFinished()) {
mCurrentPos = mScroller.getFinalX();
}
@@ -185,8 +190,8 @@
return true;
}
@Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2,
- float distanceX, float distanceY) {
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
+ float distanceY) {
int distance = (int)distanceX;
if (!mScroller.isFinished()) {
mCurrentPos = mScroller.getFinalX();
@@ -216,6 +221,24 @@
setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
+ final int action = event.getActionMasked();
+
+ final float x = event.getX();
+ final float y = event.getY();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ mInitialDownX = x;
+ mInitialDownY = y;
+ break;
+ case MotionEvent.ACTION_MOVE:
+ final float deltaX = Math.abs(x - mInitialDownX);
+ final float deltaY = Math.abs(y - mInitialDownY);
+ final int slop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
+ if (deltaX > slop && deltaX > deltaY) {
+ // Prevent the DragLayout from intercepting horizontal scrolls.
+ getParent().requestDisallowInterceptTouchEvent(true);
+ }
+ }
return mGestureDetector.onTouchEvent(event);
}
});
diff --git a/src/com/android/calculator2/DragLayout.java b/src/com/android/calculator2/DragLayout.java
index b07d087..c96d139 100644
--- a/src/com/android/calculator2/DragLayout.java
+++ b/src/com/android/calculator2/DragLayout.java
@@ -108,11 +108,17 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
- // First verify that we don't have a large deltaX (that the user is not trying to
- // horizontally scroll).
+ final int action = event.getActionMasked();
+
+ // Always handle the case of the touch gesture being complete.
+ if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
+ // Release the scroll.
+ mDragHelper.cancel();
+ return false; // Do not intercept touch event, let the child handle it
+ }
+
final float x = event.getX();
final float y = event.getY();
- final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
@@ -123,31 +129,23 @@
final float deltaX = Math.abs(x - mInitialDownX);
final float deltaY = Math.abs(y - mInitialDownY);
final int slop = mDragHelper.getTouchSlop();
- if (deltaY > slop && deltaX > deltaY) {
- mDragHelper.cancel();
+ if (deltaY > slop && deltaY > deltaX) {
+ break;
+ } else {
return false;
}
}
-
boolean doDrag = true;
for (DragCallback c : mDragCallbacks) {
- doDrag &= c.allowDrag(event);
+ doDrag &= c.shouldInterceptTouchEvent(event);
}
return doDrag && mDragHelper.shouldInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
- boolean doIntercept = true;
- for (DragCallback c : mDragCallbacks) {
- doIntercept &= c.shouldInterceptTouchEvent(event);
- }
- if (doIntercept || isMoving()) {
- mDragHelper.processTouchEvent(event);
- return true;
- } else {
- return super.onTouchEvent(event);
- }
+ mDragHelper.processTouchEvent(event);
+ return super.onTouchEvent(event);
}
@Override
@@ -215,9 +213,6 @@
// Animate the RecyclerView text.
void whileDragging(float yFraction);
- // Whether we should allow the drag to happen
- boolean allowDrag(MotionEvent event);
-
// Whether we should intercept the touch event
boolean shouldInterceptTouchEvent(MotionEvent event);
diff --git a/src/com/android/calculator2/HistoryFragment.java b/src/com/android/calculator2/HistoryFragment.java
index a96444d..6e54d9f 100644
--- a/src/com/android/calculator2/HistoryFragment.java
+++ b/src/com/android/calculator2/HistoryFragment.java
@@ -52,14 +52,8 @@
}
@Override
- public boolean allowDrag(MotionEvent event) {
- // Do not allow drag if the recycler view can move down more
- return !mRecyclerView.canScrollVertically(1);
- }
-
- @Override
public boolean shouldInterceptTouchEvent(MotionEvent event) {
- return true;
+ return !mRecyclerView.canScrollVertically(1);
}
@Override