202 lines
7.4 KiB
Java
202 lines
7.4 KiB
Java
package androidx.appcompat.widget;
|
|
|
|
import android.os.SystemClock;
|
|
import android.view.MotionEvent;
|
|
import android.view.View;
|
|
import android.view.ViewConfiguration;
|
|
import android.view.ViewParent;
|
|
import androidx.annotation.RestrictTo;
|
|
import androidx.appcompat.view.menu.ShowableListMenu;
|
|
@RestrictTo({RestrictTo.Scope.LIBRARY_GROUP_PREFIX})
|
|
public abstract class ForwardingListener implements View.OnTouchListener, View.OnAttachStateChangeListener {
|
|
private int mActivePointerId;
|
|
private Runnable mDisallowIntercept;
|
|
private boolean mForwarding;
|
|
private final int mLongPressTimeout;
|
|
private final float mScaledTouchSlop;
|
|
public final View mSrc;
|
|
private final int mTapTimeout;
|
|
private final int[] mTmpLocation = new int[2];
|
|
private Runnable mTriggerLongPress;
|
|
|
|
public class DisallowIntercept implements Runnable {
|
|
public DisallowIntercept() {
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
ViewParent parent = ForwardingListener.this.mSrc.getParent();
|
|
if (parent != null) {
|
|
parent.requestDisallowInterceptTouchEvent(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class TriggerLongPress implements Runnable {
|
|
public TriggerLongPress() {
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
ForwardingListener.this.onLongPress();
|
|
}
|
|
}
|
|
|
|
public ForwardingListener(View view) {
|
|
this.mSrc = view;
|
|
view.setLongClickable(true);
|
|
view.addOnAttachStateChangeListener(this);
|
|
this.mScaledTouchSlop = (float) ViewConfiguration.get(view.getContext()).getScaledTouchSlop();
|
|
int tapTimeout = ViewConfiguration.getTapTimeout();
|
|
this.mTapTimeout = tapTimeout;
|
|
this.mLongPressTimeout = (ViewConfiguration.getLongPressTimeout() + tapTimeout) / 2;
|
|
}
|
|
|
|
private void clearCallbacks() {
|
|
Runnable runnable = this.mTriggerLongPress;
|
|
if (runnable != null) {
|
|
this.mSrc.removeCallbacks(runnable);
|
|
}
|
|
Runnable runnable2 = this.mDisallowIntercept;
|
|
if (runnable2 != null) {
|
|
this.mSrc.removeCallbacks(runnable2);
|
|
}
|
|
}
|
|
|
|
private boolean onTouchForwarded(MotionEvent motionEvent) {
|
|
DropDownListView dropDownListView;
|
|
View view = this.mSrc;
|
|
ShowableListMenu popup = getPopup();
|
|
if (popup == null || !popup.isShowing() || (dropDownListView = (DropDownListView) popup.getListView()) == null || !dropDownListView.isShown()) {
|
|
return false;
|
|
}
|
|
MotionEvent obtainNoHistory = MotionEvent.obtainNoHistory(motionEvent);
|
|
toGlobalMotionEvent(view, obtainNoHistory);
|
|
toLocalMotionEvent(dropDownListView, obtainNoHistory);
|
|
boolean onForwardedEvent = dropDownListView.onForwardedEvent(obtainNoHistory, this.mActivePointerId);
|
|
obtainNoHistory.recycle();
|
|
int actionMasked = motionEvent.getActionMasked();
|
|
return onForwardedEvent && (actionMasked != 1 && actionMasked != 3);
|
|
}
|
|
|
|
/* JADX WARNING: Code restructure failed: missing block: B:10:0x0017, code lost:
|
|
if (r1 != 3) goto L_0x006d;
|
|
*/
|
|
private boolean onTouchObserved(MotionEvent motionEvent) {
|
|
View view = this.mSrc;
|
|
if (!view.isEnabled()) {
|
|
return false;
|
|
}
|
|
int actionMasked = motionEvent.getActionMasked();
|
|
if (actionMasked != 0) {
|
|
if (actionMasked != 1) {
|
|
if (actionMasked == 2) {
|
|
int findPointerIndex = motionEvent.findPointerIndex(this.mActivePointerId);
|
|
if (findPointerIndex >= 0 && !pointInView(view, motionEvent.getX(findPointerIndex), motionEvent.getY(findPointerIndex), this.mScaledTouchSlop)) {
|
|
clearCallbacks();
|
|
view.getParent().requestDisallowInterceptTouchEvent(true);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
clearCallbacks();
|
|
} else {
|
|
this.mActivePointerId = motionEvent.getPointerId(0);
|
|
if (this.mDisallowIntercept == null) {
|
|
this.mDisallowIntercept = new DisallowIntercept();
|
|
}
|
|
view.postDelayed(this.mDisallowIntercept, (long) this.mTapTimeout);
|
|
if (this.mTriggerLongPress == null) {
|
|
this.mTriggerLongPress = new TriggerLongPress();
|
|
}
|
|
view.postDelayed(this.mTriggerLongPress, (long) this.mLongPressTimeout);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static boolean pointInView(View view, float f, float f2, float f3) {
|
|
float f4 = -f3;
|
|
return f >= f4 && f2 >= f4 && f < ((float) (view.getRight() - view.getLeft())) + f3 && f2 < ((float) (view.getBottom() - view.getTop())) + f3;
|
|
}
|
|
|
|
private boolean toGlobalMotionEvent(View view, MotionEvent motionEvent) {
|
|
int[] iArr = this.mTmpLocation;
|
|
view.getLocationOnScreen(iArr);
|
|
motionEvent.offsetLocation((float) iArr[0], (float) iArr[1]);
|
|
return true;
|
|
}
|
|
|
|
private boolean toLocalMotionEvent(View view, MotionEvent motionEvent) {
|
|
int[] iArr = this.mTmpLocation;
|
|
view.getLocationOnScreen(iArr);
|
|
motionEvent.offsetLocation((float) (-iArr[0]), (float) (-iArr[1]));
|
|
return true;
|
|
}
|
|
|
|
public abstract ShowableListMenu getPopup();
|
|
|
|
public boolean onForwardingStarted() {
|
|
ShowableListMenu popup = getPopup();
|
|
if (popup == null || popup.isShowing()) {
|
|
return true;
|
|
}
|
|
popup.show();
|
|
return true;
|
|
}
|
|
|
|
public boolean onForwardingStopped() {
|
|
ShowableListMenu popup = getPopup();
|
|
if (popup == null || !popup.isShowing()) {
|
|
return true;
|
|
}
|
|
popup.dismiss();
|
|
return true;
|
|
}
|
|
|
|
public void onLongPress() {
|
|
clearCallbacks();
|
|
View view = this.mSrc;
|
|
if (view.isEnabled() && !view.isLongClickable() && onForwardingStarted()) {
|
|
view.getParent().requestDisallowInterceptTouchEvent(true);
|
|
long uptimeMillis = SystemClock.uptimeMillis();
|
|
MotionEvent obtain = MotionEvent.obtain(uptimeMillis, uptimeMillis, 3, 0.0f, 0.0f, 0);
|
|
view.onTouchEvent(obtain);
|
|
obtain.recycle();
|
|
this.mForwarding = true;
|
|
}
|
|
}
|
|
|
|
@Override // android.view.View.OnTouchListener
|
|
public boolean onTouch(View view, MotionEvent motionEvent) {
|
|
boolean z2;
|
|
boolean z3 = this.mForwarding;
|
|
if (z3) {
|
|
z2 = onTouchForwarded(motionEvent) || !onForwardingStopped();
|
|
} else {
|
|
z2 = onTouchObserved(motionEvent) && onForwardingStarted();
|
|
if (z2) {
|
|
long uptimeMillis = SystemClock.uptimeMillis();
|
|
MotionEvent obtain = MotionEvent.obtain(uptimeMillis, uptimeMillis, 3, 0.0f, 0.0f, 0);
|
|
this.mSrc.onTouchEvent(obtain);
|
|
obtain.recycle();
|
|
}
|
|
}
|
|
this.mForwarding = z2;
|
|
return z2 || z3;
|
|
}
|
|
|
|
@Override // android.view.View.OnAttachStateChangeListener
|
|
public void onViewAttachedToWindow(View view) {
|
|
}
|
|
|
|
@Override // android.view.View.OnAttachStateChangeListener
|
|
public void onViewDetachedFromWindow(View view) {
|
|
this.mForwarding = false;
|
|
this.mActivePointerId = -1;
|
|
Runnable runnable = this.mDisallowIntercept;
|
|
if (runnable != null) {
|
|
this.mSrc.removeCallbacks(runnable);
|
|
}
|
|
}
|
|
}
|