diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 21a8fd406e..c8e73ba8d4 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -39,7 +39,6 @@ import android.util.TypedValue; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; -import android.view.ViewConfiguration; import android.view.ViewDebug; import android.widget.TextView; @@ -109,8 +108,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, private final int mDisplay; private final CheckLongPressHelper mLongPressHelper; - private final StylusEventHelper mStylusEventHelper; - private final float mSlop; private final boolean mLayoutHorizontal; private final int mIconSize; @@ -137,9 +134,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, @ViewDebug.ExportedProperty(category = "launcher") private boolean mDisableRelayout = false; - @ViewDebug.ExportedProperty(category = "launcher") - private final boolean mIgnorePaddingTouch; - private IconLoadRequest mIconLoadRequest; public BubbleTextView(Context context) { @@ -153,7 +147,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, public BubbleTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mActivity = ActivityContext.lookupContext(context); - mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BubbleTextView, defStyle, 0); @@ -166,23 +159,19 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx); setCompoundDrawablePadding(grid.iconDrawablePaddingPx); defaultIconSize = grid.iconSizePx; - mIgnorePaddingTouch = true; } else if (mDisplay == DISPLAY_ALL_APPS) { DeviceProfile grid = mActivity.getDeviceProfile(); setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx); setCompoundDrawablePadding(grid.allAppsIconDrawablePaddingPx); defaultIconSize = grid.allAppsIconSizePx; - mIgnorePaddingTouch = true; } else if (mDisplay == DISPLAY_FOLDER) { DeviceProfile grid = mActivity.getDeviceProfile(); setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.folderChildTextSizePx); setCompoundDrawablePadding(grid.folderChildDrawablePaddingPx); defaultIconSize = grid.folderChildIconSizePx; - mIgnorePaddingTouch = true; } else { // widget_selection or shortcut_popup defaultIconSize = mActivity.getDeviceProfile().iconSizePx; - mIgnorePaddingTouch = false; } mCenterVertically = a.getBoolean(R.styleable.BubbleTextView_centerVertically, false); @@ -192,7 +181,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, a.recycle(); mLongPressHelper = new CheckLongPressHelper(this); - mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); mDotParams = new DotRenderer.DrawParams(); @@ -333,42 +321,21 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, @Override public boolean onTouchEvent(MotionEvent event) { // ignore events if they happen in padding area - if (event.getAction() == MotionEvent.ACTION_DOWN && mIgnorePaddingTouch + if (event.getAction() == MotionEvent.ACTION_DOWN && (event.getY() < getPaddingTop() || event.getX() < getPaddingLeft() || event.getY() > getHeight() - getPaddingBottom() || event.getX() > getWidth() - getPaddingRight())) { return false; } - - // Call the superclass onTouchEvent first, because sometimes it changes the state to - // isPressed() on an ACTION_UP - boolean result = super.onTouchEvent(event); - - // Check for a stylus button press, if it occurs cancel any long press checks. - if (mStylusEventHelper.onMotionEvent(event)) { - mLongPressHelper.cancelLongPress(); - result = true; + if (isLongClickable()) { + super.onTouchEvent(event); + mLongPressHelper.onTouchEvent(event); + // Keep receiving the rest of the events + return true; + } else { + return super.onTouchEvent(event); } - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - // If we're in a stylus button press, don't check for long press. - if (!mStylusEventHelper.inStylusButtonPressed()) { - mLongPressHelper.postCheckForLongPress(); - } - break; - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - mLongPressHelper.cancelLongPress(); - break; - case MotionEvent.ACTION_MOVE: - if (!Utilities.pointInView(this, event.getX(), event.getY(), mSlop)) { - mLongPressHelper.cancelLongPress(); - } - break; - } - return result; } void setStayPressed(boolean stayPressed) { @@ -531,7 +498,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, @Override public void cancelLongPress() { super.cancelLongPress(); - mLongPressHelper.cancelLongPress(); } diff --git a/src/com/android/launcher3/CheckLongPressHelper.java b/src/com/android/launcher3/CheckLongPressHelper.java index 639c173dcc..ef353f9404 100644 --- a/src/com/android/launcher3/CheckLongPressHelper.java +++ b/src/com/android/launcher3/CheckLongPressHelper.java @@ -16,46 +16,68 @@ package com.android.launcher3; +import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; -import com.android.launcher3.util.Thunk; - +/** + * Utility class to handle tripper long press on a view with custom timeout and stylus event + */ public class CheckLongPressHelper { public static final float DEFAULT_LONG_PRESS_TIMEOUT_FACTOR = 0.75f; - @Thunk View mView; - @Thunk View.OnLongClickListener mListener; - @Thunk boolean mHasPerformedLongPress; - private float mLongPressTimeoutFactor = DEFAULT_LONG_PRESS_TIMEOUT_FACTOR; - private CheckForLongPress mPendingCheckForLongPress; + private final View mView; + private final View.OnLongClickListener mListener; + private final float mSlop; - class CheckForLongPress implements Runnable { - public void run() { - if ((mView.getParent() != null) && mView.hasWindowFocus() - && !mHasPerformedLongPress) { - boolean handled; - if (mListener != null) { - handled = mListener.onLongClick(mView); - } else { - handled = mView.performLongClick(); - } - if (handled) { - mView.setPressed(false); - mHasPerformedLongPress = true; - } - } - } - } + private float mLongPressTimeoutFactor = DEFAULT_LONG_PRESS_TIMEOUT_FACTOR; + + private boolean mHasPerformedLongPress; + + private Runnable mPendingCheckForLongPress; public CheckLongPressHelper(View v) { - mView = v; + this(v, null); } public CheckLongPressHelper(View v, View.OnLongClickListener listener) { mView = v; mListener = listener; + mSlop = ViewConfiguration.get(mView.getContext()).getScaledTouchSlop(); + } + + /** + * Handles the touch event on a view + * + * @see View#onTouchEvent(MotionEvent) + */ + public void onTouchEvent(MotionEvent ev) { + switch (ev.getAction()) { + case MotionEvent.ACTION_DOWN: { + // Just in case the previous long press hasn't been cleared, we make sure to + // start fresh on touch down. + cancelLongPress(); + + postCheckForLongPress(); + if (isStylusButtonPressed(ev)) { + triggerLongPress(); + } + break; + } + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + cancelLongPress(); + break; + case MotionEvent.ACTION_MOVE: + if (!Utilities.pointInView(mView, ev.getX(), ev.getY(), mSlop)) { + cancelLongPress(); + } else if (mPendingCheckForLongPress != null && isStylusButtonPressed(ev)) { + // Only trigger long press if it has not been cancelled before + triggerLongPress(); + } + break; + } } /** @@ -65,25 +87,64 @@ public class CheckLongPressHelper { mLongPressTimeoutFactor = longPressTimeoutFactor; } - public void postCheckForLongPress() { + private void postCheckForLongPress() { mHasPerformedLongPress = false; if (mPendingCheckForLongPress == null) { - mPendingCheckForLongPress = new CheckForLongPress(); + mPendingCheckForLongPress = this::triggerLongPress; } mView.postDelayed(mPendingCheckForLongPress, (long) (ViewConfiguration.getLongPressTimeout() * mLongPressTimeoutFactor)); } + /** + * Cancels any pending long press + */ public void cancelLongPress() { mHasPerformedLongPress = false; + clearCallbacks(); + } + + /** + * Returns true if long press has been performed in the current touch gesture + */ + public boolean hasPerformedLongPress() { + return mHasPerformedLongPress; + } + + private void triggerLongPress() { + if ((mView.getParent() != null) && mView.hasWindowFocus() && !mHasPerformedLongPress) { + boolean handled; + if (mListener != null) { + handled = mListener.onLongClick(mView); + } else { + handled = mView.performLongClick(); + } + if (handled) { + mView.setPressed(false); + mHasPerformedLongPress = true; + } + clearCallbacks(); + } + } + + private void clearCallbacks() { if (mPendingCheckForLongPress != null) { mView.removeCallbacks(mPendingCheckForLongPress); mPendingCheckForLongPress = null; } } - public boolean hasPerformedLongPress() { - return mHasPerformedLongPress; + + /** + * Identifies if the provided {@link MotionEvent} is a stylus with the primary stylus button + * pressed. + * + * @param event The event to check. + * @return Whether a stylus button press occurred. + */ + private static boolean isStylusButtonPressed(MotionEvent event) { + return event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS + && event.isButtonPressed(MotionEvent.BUTTON_SECONDARY); } } diff --git a/src/com/android/launcher3/SimpleOnStylusPressListener.java b/src/com/android/launcher3/SimpleOnStylusPressListener.java deleted file mode 100644 index 6b97dcee69..0000000000 --- a/src/com/android/launcher3/SimpleOnStylusPressListener.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.android.launcher3; - -import android.view.MotionEvent; -import android.view.View; - -import com.android.launcher3.StylusEventHelper.StylusButtonListener; - -/** - * Simple listener that performs a long click on the view after a stylus button press. - */ -public class SimpleOnStylusPressListener implements StylusButtonListener { - private View mView; - - public SimpleOnStylusPressListener(View view) { - mView = view; - } - - public boolean onPressed(MotionEvent event) { - return mView.isLongClickable() && mView.performLongClick(); - } - - public boolean onReleased(MotionEvent event) { - return false; - } -} \ No newline at end of file diff --git a/src/com/android/launcher3/StylusEventHelper.java b/src/com/android/launcher3/StylusEventHelper.java deleted file mode 100644 index d5fc0fad47..0000000000 --- a/src/com/android/launcher3/StylusEventHelper.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.android.launcher3; - -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewConfiguration; - -/** - * Helper for identifying when a stylus touches a view while the primary stylus button is pressed. - * This can occur in {@value MotionEvent#ACTION_DOWN} or {@value MotionEvent#ACTION_MOVE}. - */ -public class StylusEventHelper { - - /** - * Implement this interface to receive callbacks for a stylus button press and release. - */ - public interface StylusButtonListener { - /** - * Called when the stylus button is pressed. - * - * @param event The MotionEvent that the button press occurred for. - * @return Whether the event was handled. - */ - public boolean onPressed(MotionEvent event); - - /** - * Called when the stylus button is released after a button press. This is also called if - * the event is canceled or the stylus is lifted off the screen. - * - * @param event The MotionEvent the button release occurred for. - * @return Whether the event was handled. - */ - public boolean onReleased(MotionEvent event); - } - - private boolean mIsButtonPressed; - private View mView; - private StylusButtonListener mListener; - private final float mSlop; - - /** - * Constructs a helper for listening to stylus button presses and releases. Ensure that { - * {@link #onMotionEvent(MotionEvent)} and {@link #onGenericMotionEvent(MotionEvent)} are called on - * the helper to correctly identify stylus events. - * - * @param listener The listener to call for stylus events. - * @param view Optional view associated with the touch events. - */ - public StylusEventHelper(StylusButtonListener listener, View view) { - mListener = listener; - mView = view; - if (mView != null) { - mSlop = ViewConfiguration.get(mView.getContext()).getScaledTouchSlop(); - } else { - mSlop = ViewConfiguration.getTouchSlop(); - } - } - - public boolean onMotionEvent(MotionEvent event) { - final boolean stylusButtonPressed = isStylusButtonPressed(event); - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - mIsButtonPressed = stylusButtonPressed; - if (mIsButtonPressed) { - return mListener.onPressed(event); - } - break; - case MotionEvent.ACTION_MOVE: - if (!Utilities.pointInView(mView, event.getX(), event.getY(), mSlop)) { - return false; - } - if (!mIsButtonPressed && stylusButtonPressed) { - mIsButtonPressed = true; - return mListener.onPressed(event); - } else if (mIsButtonPressed && !stylusButtonPressed) { - mIsButtonPressed = false; - return mListener.onReleased(event); - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - if (mIsButtonPressed) { - mIsButtonPressed = false; - return mListener.onReleased(event); - } - break; - } - return false; - } - - /** - * Whether a stylus button press is occurring. - */ - public boolean inStylusButtonPressed() { - return mIsButtonPressed; - } - - /** - * Identifies if the provided {@link MotionEvent} is a stylus with the primary stylus button - * pressed. - * - * @param event The event to check. - * @return Whether a stylus button press occurred. - */ - private static boolean isStylusButtonPressed(MotionEvent event) { - return event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS - && ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) - == MotionEvent.BUTTON_SECONDARY); - } -} \ No newline at end of file diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index f0d18ae63c..8251d68b70 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -31,7 +31,6 @@ import android.util.Property; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewConfiguration; import android.view.ViewDebug; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -52,8 +51,6 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherSettings; import com.android.launcher3.OnAlarmListener; import com.android.launcher3.R; -import com.android.launcher3.SimpleOnStylusPressListener; -import com.android.launcher3.StylusEventHelper; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; import com.android.launcher3.WorkspaceItemInfo; @@ -87,7 +84,6 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel private FolderInfo mInfo; private CheckLongPressHelper mLongPressHelper; - private StylusEventHelper mStylusEventHelper; static final int DROP_IN_ANIMATION_DURATION = 400; @@ -110,8 +106,6 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel boolean mAnimating = false; - private float mSlop; - private Alarm mOpenAlarm = new Alarm(); private boolean mForceHideDot; @@ -149,9 +143,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel private void init() { mLongPressHelper = new CheckLongPressHelper(this); - mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); mPreviewLayoutRule = new ClippedFolderIconLayoutRule(); - mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); mPreviewItemManager = new PreviewItemManager(this); mDotParams = new DotRenderer.DrawParams(); } @@ -663,29 +655,10 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel public boolean onTouchEvent(MotionEvent event) { // Call the superclass onTouchEvent first, because sometimes it changes the state to // isPressed() on an ACTION_UP - boolean result = super.onTouchEvent(event); - - // Check for a stylus button press, if it occurs cancel any long press checks. - if (mStylusEventHelper.onMotionEvent(event)) { - mLongPressHelper.cancelLongPress(); - return true; - } - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - mLongPressHelper.postCheckForLongPress(); - break; - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - mLongPressHelper.cancelLongPress(); - break; - case MotionEvent.ACTION_MOVE: - if (!Utilities.pointInView(this, event.getX(), event.getY(), mSlop)) { - mLongPressHelper.cancelLongPress(); - } - break; - } - return result; + super.onTouchEvent(event); + mLongPressHelper.onTouchEvent(event); + // Keep receiving the rest of the events + return true; } @Override diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java index c1310e38fb..78acc344d9 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java @@ -27,7 +27,6 @@ import android.util.SparseBooleanArray; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewConfiguration; import android.view.ViewDebug; import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; @@ -41,8 +40,6 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.R; -import com.android.launcher3.SimpleOnStylusPressListener; -import com.android.launcher3.StylusEventHelper; import com.android.launcher3.Utilities; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DraggableView; @@ -66,14 +63,11 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView protected final LayoutInflater mInflater; private final CheckLongPressHelper mLongPressHelper; - private final StylusEventHelper mStylusEventHelper; protected final Launcher mLauncher; @ViewDebug.ExportedProperty(category = "launcher") private boolean mReinflateOnConfigChange; - private float mSlop; - private boolean mIsScrollable; private boolean mIsAttachedToWindow; private boolean mIsAutoAdvanceRegistered; @@ -93,7 +87,6 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView super(context); mLauncher = Launcher.getLauncher(context); mLongPressHelper = new CheckLongPressHelper(this, this); - mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); mInflater = LayoutInflater.from(context); setAccessibilityDelegate(mLauncher.getAccessibilityDelegate()); setBackgroundResource(R.drawable.widget_internal_focus_bg); @@ -157,68 +150,19 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView } public boolean onInterceptTouchEvent(MotionEvent ev) { - // Just in case the previous long press hasn't been cleared, we make sure to start fresh - // on touch down. if (ev.getAction() == MotionEvent.ACTION_DOWN) { - mLongPressHelper.cancelLongPress(); - } - - // Consume any touch events for ourselves after longpress is triggered - if (mLongPressHelper.hasPerformedLongPress()) { - mLongPressHelper.cancelLongPress(); - return true; - } - - // Watch for longpress or stylus button press events at this level to - // make sure users can always pick up this widget - if (mStylusEventHelper.onMotionEvent(ev)) { - mLongPressHelper.cancelLongPress(); - return true; - } - - switch (ev.getAction()) { - case MotionEvent.ACTION_DOWN: { - DragLayer dragLayer = Launcher.getLauncher(getContext()).getDragLayer(); - - if (mIsScrollable) { - dragLayer.requestDisallowInterceptTouchEvent(true); - } - if (!mStylusEventHelper.inStylusButtonPressed()) { - mLongPressHelper.postCheckForLongPress(); - } - dragLayer.setTouchCompleteListener(this); - break; + DragLayer dragLayer = Launcher.getLauncher(getContext()).getDragLayer(); + if (mIsScrollable) { + dragLayer.requestDisallowInterceptTouchEvent(true); } - - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - mLongPressHelper.cancelLongPress(); - break; - case MotionEvent.ACTION_MOVE: - if (!Utilities.pointInView(this, ev.getX(), ev.getY(), mSlop)) { - mLongPressHelper.cancelLongPress(); - } - break; + dragLayer.setTouchCompleteListener(this); } - - // Otherwise continue letting touch events fall through to children - return false; + mLongPressHelper.onTouchEvent(ev); + return mLongPressHelper.hasPerformedLongPress(); } public boolean onTouchEvent(MotionEvent ev) { - // If the widget does not handle touch, then cancel - // long press when we release the touch - switch (ev.getAction()) { - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - mLongPressHelper.cancelLongPress(); - break; - case MotionEvent.ACTION_MOVE: - if (!Utilities.pointInView(this, ev.getX(), ev.getY(), mSlop)) { - mLongPressHelper.cancelLongPress(); - } - break; - } + mLongPressHelper.onTouchEvent(ev); // We want to keep receiving though events to be able to cancel long press on ACTION_UP return true; } @@ -226,7 +170,6 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); mIsAttachedToWindow = true; checkIfAutoAdvance(); diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java index f055adf102..4a0b4ef832 100644 --- a/src/com/android/launcher3/widget/WidgetCell.java +++ b/src/com/android/launcher3/widget/WidgetCell.java @@ -31,10 +31,9 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.launcher3.BaseActivity; +import com.android.launcher3.CheckLongPressHelper; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; -import com.android.launcher3.SimpleOnStylusPressListener; -import com.android.launcher3.StylusEventHelper; import com.android.launcher3.WidgetPreviewLoader; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.model.WidgetItem; @@ -71,7 +70,6 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { protected WidgetItem mItem; private WidgetPreviewLoader mWidgetPreviewLoader; - private StylusEventHelper mStylusEventHelper; protected CancellationSignal mActiveRequest; private boolean mAnimatePreview = true; @@ -80,7 +78,8 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { private Bitmap mDeferredBitmap; protected final BaseActivity mActivity; - protected DeviceProfile mDeviceProfile; + protected final DeviceProfile mDeviceProfile; + private final CheckLongPressHelper mLongPressHelper; public WidgetCell(Context context) { this(context, null); @@ -95,8 +94,9 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { mActivity = BaseActivity.fromContext(context); mDeviceProfile = mActivity.getDeviceProfile(); - mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); + mLongPressHelper = new CheckLongPressHelper(this); + mLongPressHelper.setLongPressTimeoutFactor(1); setContainerWidth(); setWillNotDraw(false); setClipToPadding(false); @@ -210,11 +210,15 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { @Override public boolean onTouchEvent(MotionEvent ev) { - boolean handled = super.onTouchEvent(ev); - if (mStylusEventHelper.onMotionEvent(ev)) { - return true; - } - return handled; + super.onTouchEvent(ev); + mLongPressHelper.onTouchEvent(ev); + return true; + } + + @Override + public void cancelLongPress() { + super.cancelLongPress(); + mLongPressHelper.cancelLongPress(); } /**