Adjust ViewDragHelper to better support watches.
ViewDragHelper hard-codes the edge size to 20dp for all devices.
On watches, this is too small. Watches should define the edge size
as a percentage of the screen height. This introduces a new method
ViewDragHelper.refreshEdgeSize() to calculate the edge size. For
phones, this will continue being 20dp, but for watches edge size
will be calculated.
Change-Id: I2d8521fab702d447b63b8508634230a5699e1a43
diff --git a/v4/java/android/support/v4/widget/ViewDragHelper.java b/v4/java/android/support/v4/widget/ViewDragHelper.java
index 3f4e571..867d326 100644
--- a/v4/java/android/support/v4/widget/ViewDragHelper.java
+++ b/v4/java/android/support/v4/widget/ViewDragHelper.java
@@ -18,6 +18,7 @@
package android.support.v4.widget;
import android.content.Context;
+import android.content.res.Configuration;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.VelocityTrackerCompat;
import android.support.v4.view.ViewCompat;
@@ -101,6 +102,12 @@
public static final int DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
private static final int EDGE_SIZE = 20; // dp
+ /**
+ * Ratio to calculate the edge size on watch devices. This is bounded by
+ * {@link #WATCH_MAX_EDGE_SIZE}.
+ */
+ private static final float WATCH_EDGE_SIZE_RATIO = .2f;
+ private static final int WATCH_MAX_EDGE_SIZE = 48; // dp
private static final int BASE_SETTLE_DURATION = 256; // ms
private static final int MAX_SETTLE_DURATION = 600; // ms
@@ -138,6 +145,9 @@
private final ViewGroup mParentView;
+ private final float mDisplayDensity;
+ private final boolean mIsUiModeTypeWatch;
+
/**
* A Callback is used as a communication channel with the ViewDragHelper back to the
* parent view using it. <code>on*</code>methods are invoked on siginficant events and several
@@ -381,10 +391,12 @@
mParentView = forParent;
mCallback = cb;
- final ViewConfiguration vc = ViewConfiguration.get(context);
- final float density = context.getResources().getDisplayMetrics().density;
- mEdgeSize = (int) (EDGE_SIZE * density + 0.5f);
+ mDisplayDensity = context.getResources().getDisplayMetrics().density;
+ mIsUiModeTypeWatch = (context.getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_WATCH;
+ refreshEdgeSize();
+ final ViewConfiguration vc = ViewConfiguration.get(context);
mTouchSlop = vc.getScaledTouchSlop();
mMaxVelocity = vc.getScaledMaximumFlingVelocity();
mMinVelocity = vc.getScaledMinimumFlingVelocity();
@@ -449,6 +461,21 @@
}
/**
+ * Refreshes the edge size. This can be used if the edge size should change depending on the
+ * size of the {@link ViewGroup}. A good time to call this method is during
+ * {@link View#onSizeChanged()}.
+ */
+ public void refreshEdgeSize() {
+ if (mIsUiModeTypeWatch) {
+ int edgeSizePx = (int) (WATCH_EDGE_SIZE_RATIO * mParentView.getHeight());
+ int maxEdgeSizePx = (int) (WATCH_MAX_EDGE_SIZE * mDisplayDensity);
+ mEdgeSize = Math.min(edgeSizePx, maxEdgeSizePx);
+ } else {
+ mEdgeSize = (int) (EDGE_SIZE * mDisplayDensity + 0.5f);
+ }
+ }
+
+ /**
* Capture a specific child view for dragging within the parent. The callback will be notified
* but {@link Callback#tryCaptureView(android.view.View, int)} will not be asked permission to
* capture this view.
@@ -1479,4 +1506,4 @@
return result;
}
-}
\ No newline at end of file
+}