summaryrefslogtreecommitdiff
path: root/android/view/TouchDelegate.java
diff options
context:
space:
mode:
authorJustin Klaassen <justinklaassen@google.com>2017-09-15 17:58:39 -0400
committerJustin Klaassen <justinklaassen@google.com>2017-09-15 17:58:39 -0400
commit10d07c88d69cc64f73a069163e7ea5ba2519a099 (patch)
tree8dbd149eb350320a29c3d10e7ad3201de1c5cbee /android/view/TouchDelegate.java
parent677516fb6b6f207d373984757d3d9450474b6b00 (diff)
downloadandroid-28-10d07c88d69cc64f73a069163e7ea5ba2519a099.tar.gz
Import Android SDK Platform PI [4335822]
/google/data/ro/projects/android/fetch_artifact \ --bid 4335822 \ --target sdk_phone_armv7-win_sdk \ sdk-repo-linux-sources-4335822.zip AndroidVersion.ApiLevel has been modified to appear as 28 Change-Id: Ic8f04be005a71c2b9abeaac754d8da8d6f9a2c32
Diffstat (limited to 'android/view/TouchDelegate.java')
-rw-r--r--android/view/TouchDelegate.java150
1 files changed, 150 insertions, 0 deletions
diff --git a/android/view/TouchDelegate.java b/android/view/TouchDelegate.java
new file mode 100644
index 00000000..cf36f436
--- /dev/null
+++ b/android/view/TouchDelegate.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.graphics.Rect;
+
+/**
+ * Helper class to handle situations where you want a view to have a larger touch area than its
+ * actual view bounds. The view whose touch area is changed is called the delegate view. This
+ * class should be used by an ancestor of the delegate. To use a TouchDelegate, first create an
+ * instance that specifies the bounds that should be mapped to the delegate and the delegate
+ * view itself.
+ * <p>
+ * The ancestor should then forward all of its touch events received in its
+ * {@link android.view.View#onTouchEvent(MotionEvent)} to {@link #onTouchEvent(MotionEvent)}.
+ * </p>
+ */
+public class TouchDelegate {
+
+ /**
+ * View that should receive forwarded touch events
+ */
+ private View mDelegateView;
+
+ /**
+ * Bounds in local coordinates of the containing view that should be mapped to the delegate
+ * view. This rect is used for initial hit testing.
+ */
+ private Rect mBounds;
+
+ /**
+ * mBounds inflated to include some slop. This rect is to track whether the motion events
+ * should be considered to be be within the delegate view.
+ */
+ private Rect mSlopBounds;
+
+ /**
+ * True if the delegate had been targeted on a down event (intersected mBounds).
+ */
+ private boolean mDelegateTargeted;
+
+ /**
+ * The touchable region of the View extends above its actual extent.
+ */
+ public static final int ABOVE = 1;
+
+ /**
+ * The touchable region of the View extends below its actual extent.
+ */
+ public static final int BELOW = 2;
+
+ /**
+ * The touchable region of the View extends to the left of its
+ * actual extent.
+ */
+ public static final int TO_LEFT = 4;
+
+ /**
+ * The touchable region of the View extends to the right of its
+ * actual extent.
+ */
+ public static final int TO_RIGHT = 8;
+
+ private int mSlop;
+
+ /**
+ * Constructor
+ *
+ * @param bounds Bounds in local coordinates of the containing view that should be mapped to
+ * the delegate view
+ * @param delegateView The view that should receive motion events
+ */
+ public TouchDelegate(Rect bounds, View delegateView) {
+ mBounds = bounds;
+
+ mSlop = ViewConfiguration.get(delegateView.getContext()).getScaledTouchSlop();
+ mSlopBounds = new Rect(bounds);
+ mSlopBounds.inset(-mSlop, -mSlop);
+ mDelegateView = delegateView;
+ }
+
+ /**
+ * Will forward touch events to the delegate view if the event is within the bounds
+ * specified in the constructor.
+ *
+ * @param event The touch event to forward
+ * @return True if the event was forwarded to the delegate, false otherwise.
+ */
+ public boolean onTouchEvent(MotionEvent event) {
+ int x = (int)event.getX();
+ int y = (int)event.getY();
+ boolean sendToDelegate = false;
+ boolean hit = true;
+ boolean handled = false;
+
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ Rect bounds = mBounds;
+
+ if (bounds.contains(x, y)) {
+ mDelegateTargeted = true;
+ sendToDelegate = true;
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_MOVE:
+ sendToDelegate = mDelegateTargeted;
+ if (sendToDelegate) {
+ Rect slopBounds = mSlopBounds;
+ if (!slopBounds.contains(x, y)) {
+ hit = false;
+ }
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ sendToDelegate = mDelegateTargeted;
+ mDelegateTargeted = false;
+ break;
+ }
+ if (sendToDelegate) {
+ final View delegateView = mDelegateView;
+
+ if (hit) {
+ // Offset event coordinates to be inside the target view
+ event.setLocation(delegateView.getWidth() / 2, delegateView.getHeight() / 2);
+ } else {
+ // Offset event coordinates to be outside the target view (in case it does
+ // something like tracking pressed state)
+ int slop = mSlop;
+ event.setLocation(-(slop * 2), -(slop * 2));
+ }
+ handled = delegateView.dispatchTouchEvent(event);
+ }
+ return handled;
+ }
+}