Loading core/java/android/widget/ListPopupWindow.java +142 −27 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.View.MeasureSpec; import android.view.View.OnTouchListener; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; import android.view.animation.AccelerateDecelerateInterpolator; Loading Loading @@ -960,33 +961,6 @@ public class ListPopupWindow { return false; } /** * Receives motion events forwarded from a source view. This is used * internally to implement support for drag-to-open. * * @param src view from which the event was forwarded * @param srcEvent forwarded motion event in source-local coordinates * @param activePointerId id of the pointer that activated forwarding * @return whether the event was handled * @hide */ public boolean onForwardedEvent(View src, MotionEvent srcEvent, int activePointerId) { final DropDownListView dst = mDropDownList; if (dst == null || !dst.isShown()) { return false; } // Convert event to local coordinates. final MotionEvent dstEvent = MotionEvent.obtainNoHistory(srcEvent); src.toGlobalMotionEvent(dstEvent); dst.toLocalMotionEvent(dstEvent); // Forward converted event, then recycle it. final boolean handled = dst.onForwardedEvent(dstEvent, activePointerId); dstEvent.recycle(); return handled; } /** * <p>Builds the popup window's content and returns the height the popup * should have. Returns -1 when the content already exists.</p> Loading Loading @@ -1154,6 +1128,147 @@ public class ListPopupWindow { return listContent + otherHeights; } /** * Abstract class that forwards touch events to a {@link ListPopupWindow}. * * @hide */ public static abstract class ForwardingListener implements View.OnTouchListener { /** Scaled touch slop, used for detecting movement outside bounds. */ private final float mScaledTouchSlop; /** Whether this listener is currently forwarding touch events. */ private boolean mForwarding; /** The id of the first pointer down in the current event stream. */ private int mActivePointerId; public ForwardingListener(Context context) { mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } /** * Returns the popup to which this listener is forwarding events. * <p> * Override this to return the correct popup. If the popup is displayed * asynchronously, you may also need to override * {@link #onForwardingStopped} to prevent premature cancelation of * forwarding. * * @return the popup to which this listener is forwarding events */ public abstract ListPopupWindow getPopup(); @Override public boolean onTouch(View v, MotionEvent event) { final boolean wasForwarding = mForwarding; final boolean forwarding; if (wasForwarding) { forwarding = onTouchForwarded(v, event) || !onForwardingStopped(); } else { forwarding = onTouchObserved(v, event) && onForwardingStarted(); } mForwarding = forwarding; return forwarding || wasForwarding; } /** * Called when forwarding would like to start. * <p> * By default, this will show the popup returned by {@link #getPopup()}. * It may be overridden to perform another action, like clicking the * source view or preparing the popup before showing it. * * @return true to start forwarding, false otherwise */ public boolean onForwardingStarted() { final ListPopupWindow popup = getPopup(); if (popup != null && !popup.isShowing()) { popup.show(); } return true; } /** * Called when forwarding would like to stop. * <p> * By default, this will dismiss the popup returned by * {@link #getPopup()}. It may be overridden to perform some other * action. * * @return true to stop forwarding, false otherwise */ public boolean onForwardingStopped() { final ListPopupWindow popup = getPopup(); if (popup != null && popup.isShowing()) { popup.dismiss(); } return true; } /** * Observes motion events and determines when to start forwarding. * * @param src view from which the event originated * @param srcEvent motion event in source view coordinates * @return true to start forwarding motion events, false otherwise */ private boolean onTouchObserved(View src, MotionEvent srcEvent) { if (!src.isEnabled()) { return false; } // The first pointer down is always the active pointer. final int actionMasked = srcEvent.getActionMasked(); if (actionMasked == MotionEvent.ACTION_DOWN) { mActivePointerId = srcEvent.getPointerId(0); } final int activePointerIndex = srcEvent.findPointerIndex(mActivePointerId); if (activePointerIndex >= 0) { final float x = srcEvent.getX(activePointerIndex); final float y = srcEvent.getY(activePointerIndex); if (!src.pointInView(x, y, mScaledTouchSlop)) { // The pointer has moved outside of the view. return true; } } return false; } /** * Handled forwarded motion events and determines when to stop * forwarding. * * @param src view from which the event originated * @param srcEvent motion event in source view coordinates * @return true to continue forwarding motion events, false to cancel */ private boolean onTouchForwarded(View src, MotionEvent srcEvent) { final ListPopupWindow popup = getPopup(); if (popup == null || !popup.isShowing()) { return false; } final DropDownListView dst = popup.mDropDownList; if (dst == null || !dst.isShown()) { return false; } // Convert event to destination-local coordinates. final MotionEvent dstEvent = MotionEvent.obtainNoHistory(srcEvent); src.toGlobalMotionEvent(dstEvent); dst.toLocalMotionEvent(dstEvent); // Forward converted event to destination view, then recycle it. final boolean handled = dst.onForwardedEvent(dstEvent, mActivePointerId); dstEvent.recycle(); return handled; } } /** * <p>Wrapper class for a ListView. This wrapper can hijack the focus to * make sure the list uses the appropriate drawables and states when Loading core/java/android/widget/Spinner.java +30 −2 Original line number Diff line number Diff line Loading @@ -30,12 +30,14 @@ import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ListPopupWindow.ForwardingListener; import android.widget.PopupWindow.OnDismissListener; Loading Loading @@ -77,6 +79,9 @@ public class Spinner extends AbsSpinner implements OnClickListener { */ private static final int MODE_THEME = -1; /** Forwarding listener used to implement drag-to-open. */ private ForwardingListener mForwardingListener; private SpinnerPopup mPopup; private DropDownAdapter mTempAdapter; int mDropDownWidth; Loading Loading @@ -173,7 +178,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { } case MODE_DROPDOWN: { DropdownPopup popup = new DropdownPopup(context, attrs, defStyle); final DropdownPopup popup = new DropdownPopup(context, attrs, defStyle); mDropDownWidth = a.getLayoutDimension( com.android.internal.R.styleable.Spinner_dropDownWidth, Loading @@ -193,6 +198,20 @@ public class Spinner extends AbsSpinner implements OnClickListener { } mPopup = popup; mForwardingListener = new ForwardingListener(context) { @Override public ListPopupWindow getPopup() { return popup; } @Override public boolean onForwardingStarted() { if (!mPopup.isShowing()) { mPopup.show(getTextDirection(), getTextAlignment()); } return true; } }; break; } } Loading Loading @@ -448,6 +467,15 @@ public class Spinner extends AbsSpinner implements OnClickListener { super.setOnItemClickListener(l); } @Override public boolean onTouchEvent(MotionEvent event) { if (mForwardingListener != null && mForwardingListener.onTouch(this, event)) { return true; } return super.onTouchEvent(event); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Loading core/java/com/android/internal/view/menu/ActionMenuPresenter.java +32 −53 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ import android.view.View.MeasureSpec; import android.view.accessibility.AccessibilityNodeInfo; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ListPopupWindow; import android.widget.ListPopupWindow.ForwardingListener; import com.android.internal.view.ActionBarPolicy; import com.android.internal.view.menu.ActionMenuView.ActionMenuChildView; Loading Loading @@ -562,7 +564,36 @@ public class ActionMenuPresenter extends BaseMenuPresenter setFocusable(true); setVisibility(VISIBLE); setEnabled(true); setOnTouchListener(new OverflowForwardListener(context)); setOnTouchListener(new ForwardingListener(context) { @Override public ListPopupWindow getPopup() { if (mOverflowPopup == null) { return null; } return mOverflowPopup.getPopup(); } @Override public boolean onForwardingStarted() { showOverflowMenu(); return true; } @Override public boolean onForwardingStopped() { // Displaying the popup occurs asynchronously, so wait for // the runnable to finish before deciding whether to stop // forwarding. if (mPostedOpenRunnable != null) { return false; } hideOverflowMenu(); return true; } }); } @Override Loading Loading @@ -687,56 +718,4 @@ public class ActionMenuPresenter extends BaseMenuPresenter mPostedOpenRunnable = null; } } private class OverflowForwardListener extends TouchForwardingListener { /** Scaled touch slop, used for detecting movement outside bounds. */ private final float mScaledTouchSlop; private int mActivePointerId = MotionEvent.INVALID_POINTER_ID; public OverflowForwardListener(Context context) { mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } @Override public boolean onTouchObserved(View src, MotionEvent srcEvent) { if (!src.isEnabled()) { return false; } // Always start forwarding events when the source view is touched. mActivePointerId = srcEvent.getPointerId(0); src.performClick(); return true; } @Override public boolean onTouchForwarded(View src, MotionEvent srcEvent) { final OverflowPopup popup = mOverflowPopup; if (popup != null && popup.isShowing()) { final int activePointerId = mActivePointerId; if (activePointerId != MotionEvent.INVALID_POINTER_ID && src.isEnabled() && popup.forwardMotionEvent(src, srcEvent, activePointerId)) { // Handled the motion event, continue forwarding. return true; } final int activePointerIndex = srcEvent.findPointerIndex(activePointerId); if (activePointerIndex >= 0) { final float x = srcEvent.getX(activePointerIndex); final float y = srcEvent.getY(activePointerIndex); if (src.pointInView(x, y, mScaledTouchSlop)) { // The user is touching the source view. Cancel // forwarding, but don't dismiss the popup. return false; } } popup.dismiss(); } // Cancel forwarding. return false; } } } core/java/com/android/internal/view/menu/MenuPopupHelper.java +4 −16 Original line number Diff line number Diff line Loading @@ -108,6 +108,10 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On } } public ListPopupWindow getPopup() { return mPopup; } public boolean tryShow() { mPopup = new ListPopupWindow(mContext, null, com.android.internal.R.attr.popupMenuStyle); mPopup.setOnDismissListener(this); Loading Loading @@ -159,22 +163,6 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On return mPopup != null && mPopup.isShowing(); } /** * Forwards motion events from a source view to the popup window. * * @param src view from which the event was forwarded * @param event forwarded motion event in source-local coordinates * @param activePointerId id of the pointer that activated forwarding * @return whether the event was handled */ public boolean forwardMotionEvent(View src, MotionEvent event, int activePointerId) { if (mPopup == null || !mPopup.isShowing()) { return false; } return mPopup.onForwardedEvent(src, event, activePointerId); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { MenuAdapter adapter = mAdapter; Loading core/java/com/android/internal/view/menu/TouchForwardingListener.javadeleted 100644 → 0 +0 −72 Original line number Diff line number Diff line /* * Copyright (C) 2013 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 com.android.internal.view.menu; import android.view.MotionEvent; import android.view.View; /** * Touch listener used to intercept touches and forward them out of a view. */ abstract class TouchForwardingListener implements View.OnTouchListener { /** Whether this listener is currently forwarding touch events. */ private boolean mForwarding; @Override public boolean onTouch(View v, MotionEvent ev) { final int actionMasked = ev.getActionMasked(); if (mForwarding) { // Rejecting the event or ending the stream stops forwarding. if (!onTouchForwarded(v, ev) || actionMasked == MotionEvent.ACTION_UP || actionMasked == MotionEvent.ACTION_CANCEL) { stopForwarding(); } } else { if (onTouchObserved(v, ev)) { startForwarding(); } } return mForwarding; } public void startForwarding() { mForwarding = true; } public void stopForwarding() { mForwarding = false; } /** * Attempts to start forwarding motion events. * * @param v The view that triggered forwarding. * @return True to start forwarding motion events, or false to cancel. */ public abstract boolean onTouchObserved(View v, MotionEvent ev); /** * Handles forwarded motion events. * * @param v The view from which the event was forwarded. * @param ev The forwarded motion event. * @return True to continue forwarding motion events, or false to cancel. */ public abstract boolean onTouchForwarded(View v, MotionEvent ev); } Loading
core/java/android/widget/ListPopupWindow.java +142 −27 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.View.MeasureSpec; import android.view.View.OnTouchListener; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; import android.view.animation.AccelerateDecelerateInterpolator; Loading Loading @@ -960,33 +961,6 @@ public class ListPopupWindow { return false; } /** * Receives motion events forwarded from a source view. This is used * internally to implement support for drag-to-open. * * @param src view from which the event was forwarded * @param srcEvent forwarded motion event in source-local coordinates * @param activePointerId id of the pointer that activated forwarding * @return whether the event was handled * @hide */ public boolean onForwardedEvent(View src, MotionEvent srcEvent, int activePointerId) { final DropDownListView dst = mDropDownList; if (dst == null || !dst.isShown()) { return false; } // Convert event to local coordinates. final MotionEvent dstEvent = MotionEvent.obtainNoHistory(srcEvent); src.toGlobalMotionEvent(dstEvent); dst.toLocalMotionEvent(dstEvent); // Forward converted event, then recycle it. final boolean handled = dst.onForwardedEvent(dstEvent, activePointerId); dstEvent.recycle(); return handled; } /** * <p>Builds the popup window's content and returns the height the popup * should have. Returns -1 when the content already exists.</p> Loading Loading @@ -1154,6 +1128,147 @@ public class ListPopupWindow { return listContent + otherHeights; } /** * Abstract class that forwards touch events to a {@link ListPopupWindow}. * * @hide */ public static abstract class ForwardingListener implements View.OnTouchListener { /** Scaled touch slop, used for detecting movement outside bounds. */ private final float mScaledTouchSlop; /** Whether this listener is currently forwarding touch events. */ private boolean mForwarding; /** The id of the first pointer down in the current event stream. */ private int mActivePointerId; public ForwardingListener(Context context) { mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } /** * Returns the popup to which this listener is forwarding events. * <p> * Override this to return the correct popup. If the popup is displayed * asynchronously, you may also need to override * {@link #onForwardingStopped} to prevent premature cancelation of * forwarding. * * @return the popup to which this listener is forwarding events */ public abstract ListPopupWindow getPopup(); @Override public boolean onTouch(View v, MotionEvent event) { final boolean wasForwarding = mForwarding; final boolean forwarding; if (wasForwarding) { forwarding = onTouchForwarded(v, event) || !onForwardingStopped(); } else { forwarding = onTouchObserved(v, event) && onForwardingStarted(); } mForwarding = forwarding; return forwarding || wasForwarding; } /** * Called when forwarding would like to start. * <p> * By default, this will show the popup returned by {@link #getPopup()}. * It may be overridden to perform another action, like clicking the * source view or preparing the popup before showing it. * * @return true to start forwarding, false otherwise */ public boolean onForwardingStarted() { final ListPopupWindow popup = getPopup(); if (popup != null && !popup.isShowing()) { popup.show(); } return true; } /** * Called when forwarding would like to stop. * <p> * By default, this will dismiss the popup returned by * {@link #getPopup()}. It may be overridden to perform some other * action. * * @return true to stop forwarding, false otherwise */ public boolean onForwardingStopped() { final ListPopupWindow popup = getPopup(); if (popup != null && popup.isShowing()) { popup.dismiss(); } return true; } /** * Observes motion events and determines when to start forwarding. * * @param src view from which the event originated * @param srcEvent motion event in source view coordinates * @return true to start forwarding motion events, false otherwise */ private boolean onTouchObserved(View src, MotionEvent srcEvent) { if (!src.isEnabled()) { return false; } // The first pointer down is always the active pointer. final int actionMasked = srcEvent.getActionMasked(); if (actionMasked == MotionEvent.ACTION_DOWN) { mActivePointerId = srcEvent.getPointerId(0); } final int activePointerIndex = srcEvent.findPointerIndex(mActivePointerId); if (activePointerIndex >= 0) { final float x = srcEvent.getX(activePointerIndex); final float y = srcEvent.getY(activePointerIndex); if (!src.pointInView(x, y, mScaledTouchSlop)) { // The pointer has moved outside of the view. return true; } } return false; } /** * Handled forwarded motion events and determines when to stop * forwarding. * * @param src view from which the event originated * @param srcEvent motion event in source view coordinates * @return true to continue forwarding motion events, false to cancel */ private boolean onTouchForwarded(View src, MotionEvent srcEvent) { final ListPopupWindow popup = getPopup(); if (popup == null || !popup.isShowing()) { return false; } final DropDownListView dst = popup.mDropDownList; if (dst == null || !dst.isShown()) { return false; } // Convert event to destination-local coordinates. final MotionEvent dstEvent = MotionEvent.obtainNoHistory(srcEvent); src.toGlobalMotionEvent(dstEvent); dst.toLocalMotionEvent(dstEvent); // Forward converted event to destination view, then recycle it. final boolean handled = dst.onForwardedEvent(dstEvent, mActivePointerId); dstEvent.recycle(); return handled; } } /** * <p>Wrapper class for a ListView. This wrapper can hijack the focus to * make sure the list uses the appropriate drawables and states when Loading
core/java/android/widget/Spinner.java +30 −2 Original line number Diff line number Diff line Loading @@ -30,12 +30,14 @@ import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.ListPopupWindow.ForwardingListener; import android.widget.PopupWindow.OnDismissListener; Loading Loading @@ -77,6 +79,9 @@ public class Spinner extends AbsSpinner implements OnClickListener { */ private static final int MODE_THEME = -1; /** Forwarding listener used to implement drag-to-open. */ private ForwardingListener mForwardingListener; private SpinnerPopup mPopup; private DropDownAdapter mTempAdapter; int mDropDownWidth; Loading Loading @@ -173,7 +178,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { } case MODE_DROPDOWN: { DropdownPopup popup = new DropdownPopup(context, attrs, defStyle); final DropdownPopup popup = new DropdownPopup(context, attrs, defStyle); mDropDownWidth = a.getLayoutDimension( com.android.internal.R.styleable.Spinner_dropDownWidth, Loading @@ -193,6 +198,20 @@ public class Spinner extends AbsSpinner implements OnClickListener { } mPopup = popup; mForwardingListener = new ForwardingListener(context) { @Override public ListPopupWindow getPopup() { return popup; } @Override public boolean onForwardingStarted() { if (!mPopup.isShowing()) { mPopup.show(getTextDirection(), getTextAlignment()); } return true; } }; break; } } Loading Loading @@ -448,6 +467,15 @@ public class Spinner extends AbsSpinner implements OnClickListener { super.setOnItemClickListener(l); } @Override public boolean onTouchEvent(MotionEvent event) { if (mForwardingListener != null && mForwardingListener.onTouch(this, event)) { return true; } return super.onTouchEvent(event); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Loading
core/java/com/android/internal/view/menu/ActionMenuPresenter.java +32 −53 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ import android.view.View.MeasureSpec; import android.view.accessibility.AccessibilityNodeInfo; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ListPopupWindow; import android.widget.ListPopupWindow.ForwardingListener; import com.android.internal.view.ActionBarPolicy; import com.android.internal.view.menu.ActionMenuView.ActionMenuChildView; Loading Loading @@ -562,7 +564,36 @@ public class ActionMenuPresenter extends BaseMenuPresenter setFocusable(true); setVisibility(VISIBLE); setEnabled(true); setOnTouchListener(new OverflowForwardListener(context)); setOnTouchListener(new ForwardingListener(context) { @Override public ListPopupWindow getPopup() { if (mOverflowPopup == null) { return null; } return mOverflowPopup.getPopup(); } @Override public boolean onForwardingStarted() { showOverflowMenu(); return true; } @Override public boolean onForwardingStopped() { // Displaying the popup occurs asynchronously, so wait for // the runnable to finish before deciding whether to stop // forwarding. if (mPostedOpenRunnable != null) { return false; } hideOverflowMenu(); return true; } }); } @Override Loading Loading @@ -687,56 +718,4 @@ public class ActionMenuPresenter extends BaseMenuPresenter mPostedOpenRunnable = null; } } private class OverflowForwardListener extends TouchForwardingListener { /** Scaled touch slop, used for detecting movement outside bounds. */ private final float mScaledTouchSlop; private int mActivePointerId = MotionEvent.INVALID_POINTER_ID; public OverflowForwardListener(Context context) { mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } @Override public boolean onTouchObserved(View src, MotionEvent srcEvent) { if (!src.isEnabled()) { return false; } // Always start forwarding events when the source view is touched. mActivePointerId = srcEvent.getPointerId(0); src.performClick(); return true; } @Override public boolean onTouchForwarded(View src, MotionEvent srcEvent) { final OverflowPopup popup = mOverflowPopup; if (popup != null && popup.isShowing()) { final int activePointerId = mActivePointerId; if (activePointerId != MotionEvent.INVALID_POINTER_ID && src.isEnabled() && popup.forwardMotionEvent(src, srcEvent, activePointerId)) { // Handled the motion event, continue forwarding. return true; } final int activePointerIndex = srcEvent.findPointerIndex(activePointerId); if (activePointerIndex >= 0) { final float x = srcEvent.getX(activePointerIndex); final float y = srcEvent.getY(activePointerIndex); if (src.pointInView(x, y, mScaledTouchSlop)) { // The user is touching the source view. Cancel // forwarding, but don't dismiss the popup. return false; } } popup.dismiss(); } // Cancel forwarding. return false; } } }
core/java/com/android/internal/view/menu/MenuPopupHelper.java +4 −16 Original line number Diff line number Diff line Loading @@ -108,6 +108,10 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On } } public ListPopupWindow getPopup() { return mPopup; } public boolean tryShow() { mPopup = new ListPopupWindow(mContext, null, com.android.internal.R.attr.popupMenuStyle); mPopup.setOnDismissListener(this); Loading Loading @@ -159,22 +163,6 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On return mPopup != null && mPopup.isShowing(); } /** * Forwards motion events from a source view to the popup window. * * @param src view from which the event was forwarded * @param event forwarded motion event in source-local coordinates * @param activePointerId id of the pointer that activated forwarding * @return whether the event was handled */ public boolean forwardMotionEvent(View src, MotionEvent event, int activePointerId) { if (mPopup == null || !mPopup.isShowing()) { return false; } return mPopup.onForwardedEvent(src, event, activePointerId); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { MenuAdapter adapter = mAdapter; Loading
core/java/com/android/internal/view/menu/TouchForwardingListener.javadeleted 100644 → 0 +0 −72 Original line number Diff line number Diff line /* * Copyright (C) 2013 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 com.android.internal.view.menu; import android.view.MotionEvent; import android.view.View; /** * Touch listener used to intercept touches and forward them out of a view. */ abstract class TouchForwardingListener implements View.OnTouchListener { /** Whether this listener is currently forwarding touch events. */ private boolean mForwarding; @Override public boolean onTouch(View v, MotionEvent ev) { final int actionMasked = ev.getActionMasked(); if (mForwarding) { // Rejecting the event or ending the stream stops forwarding. if (!onTouchForwarded(v, ev) || actionMasked == MotionEvent.ACTION_UP || actionMasked == MotionEvent.ACTION_CANCEL) { stopForwarding(); } } else { if (onTouchObserved(v, ev)) { startForwarding(); } } return mForwarding; } public void startForwarding() { mForwarding = true; } public void stopForwarding() { mForwarding = false; } /** * Attempts to start forwarding motion events. * * @param v The view that triggered forwarding. * @return True to start forwarding motion events, or false to cancel. */ public abstract boolean onTouchObserved(View v, MotionEvent ev); /** * Handles forwarded motion events. * * @param v The view from which the event was forwarded. * @param ev The forwarded motion event. * @return True to continue forwarding motion events, or false to cancel. */ public abstract boolean onTouchForwarded(View v, MotionEvent ev); }