use of android.view.ViewParent in project AutoLoadListView by ZhaoKaiQiang.
the class ZSwipeItem method onTouchEvent.
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabledInAdapterView() || !isEnabled())
return true;
if (!isSwipeEnabled())
return super.onTouchEvent(event);
int action = event.getActionMasked();
ViewParent parent = getParent();
gestureDetector.onTouchEvent(event);
Status status = getOpenStatus();
ViewGroup touching = null;
if (status == Status.Close) {
touching = getSurfaceView();
} else if (status == Status.Open) {
touching = getBottomView();
}
switch(action) {
case MotionEvent.ACTION_DOWN:
mDragHelper.processTouchEvent(event);
parent.requestDisallowInterceptTouchEvent(true);
sX = event.getRawX();
sY = event.getRawY();
if (touching != null)
touching.setPressed(true);
return true;
case MotionEvent.ACTION_MOVE:
{
if (sX == -1 || sY == -1) {
// Trick:
// When in nested mode, we need to send a constructed
// ACTION_DOWN MotionEvent to mDragHelper, to help
// it initialize itself.
event.setAction(MotionEvent.ACTION_DOWN);
mDragHelper.processTouchEvent(event);
parent.requestDisallowInterceptTouchEvent(true);
sX = event.getRawX();
sY = event.getRawY();
return true;
}
float distanceX = event.getRawX() - sX;
float distanceY = event.getRawY() - sY;
float angle = Math.abs(distanceY / distanceX);
angle = (float) Math.toDegrees(Math.atan(angle));
boolean doNothing = false;
// 根据触摸角度,判断是否执行用户操作
if (mDragEdge == DragEdge.Right) {
boolean suitable = (status == Status.Open && distanceX > 0) || (status == Status.Close && distanceX < 0);
suitable = suitable || (status == Status.Middle);
if (angle > 30 || !suitable) {
doNothing = true;
}
}
if (mDragEdge == DragEdge.Left) {
boolean suitable = (status == Status.Open && distanceX < 0) || (status == Status.Close && distanceX > 0);
suitable = suitable || status == Status.Middle;
if (angle > 30 || !suitable) {
doNothing = true;
}
}
if (mDragEdge == DragEdge.Top) {
boolean suitable = (status == Status.Open && distanceY < 0) || (status == Status.Close && distanceY > 0);
suitable = suitable || status == Status.Middle;
if (angle < 60 || !suitable) {
doNothing = true;
}
}
if (mDragEdge == DragEdge.Bottom) {
boolean suitable = (status == Status.Open && distanceY > 0) || (status == Status.Close && distanceY < 0);
suitable = suitable || status == Status.Middle;
if (angle < 60 || !suitable) {
doNothing = true;
}
}
if (doNothing) {
// 拦截触摸事件
parent.requestDisallowInterceptTouchEvent(false);
return false;
} else {
if (touching != null) {
touching.setPressed(false);
}
parent.requestDisallowInterceptTouchEvent(true);
mDragHelper.processTouchEvent(event);
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
{
sX = -1;
sY = -1;
if (touching != null) {
touching.setPressed(false);
}
}
default:
parent.requestDisallowInterceptTouchEvent(true);
mDragHelper.processTouchEvent(event);
}
return true;
}
use of android.view.ViewParent in project Carbon by ZieIony.
the class ItemTouchHelper method select.
/**
* Starts dragging or swiping the given View. Call with null if you want to clear it.
*
* @param selected The RowViewHolder to drag or swipe. Can be null if you want to cancel the
* current action
* @param actionState The type of action
*/
private void select(ViewHolder selected, int actionState) {
if (selected == mSelected && actionState == mActionState) {
return;
}
mDragScrollStartTimeInMs = Long.MIN_VALUE;
final int prevActionState = mActionState;
// prevent duplicate animations
endRecoverAnimation(selected, true);
mActionState = actionState;
if (actionState == ACTION_STATE_DRAG) {
// we remove after animation is complete. this means we only elevate the last drag
// child but that should perform good enough as it is very hard to start dragging a
// new child before the previous one settles.
mOverdrawChild = selected.itemView;
addChildDrawingOrderCallback();
}
int actionStateMask = (1 << (DIRECTION_FLAG_COUNT + DIRECTION_FLAG_COUNT * actionState)) - 1;
boolean preventLayout = false;
if (mSelected != null) {
final ViewHolder prevSelected = mSelected;
if (prevSelected.itemView.getParent() != null) {
final int swipeDir = prevActionState == ACTION_STATE_DRAG ? 0 : swipeIfNecessary(prevSelected);
releaseVelocityTracker();
// find where we should animate to
final float targetTranslateX, targetTranslateY;
int animationType;
switch(swipeDir) {
case LEFT:
case RIGHT:
case START:
case END:
targetTranslateY = 0;
targetTranslateX = Math.signum(mDx) * mRecyclerView.getWidth();
break;
case UP:
case DOWN:
targetTranslateX = 0;
targetTranslateY = Math.signum(mDy) * mRecyclerView.getHeight();
break;
default:
targetTranslateX = 0;
targetTranslateY = 0;
}
if (prevActionState == ACTION_STATE_DRAG) {
animationType = ANIMATION_TYPE_DRAG;
} else if (swipeDir > 0) {
animationType = ANIMATION_TYPE_SWIPE_SUCCESS;
} else {
animationType = ANIMATION_TYPE_SWIPE_CANCEL;
}
getSelectedDxDy(mTmpPosition);
final float currentTranslateX = mTmpPosition[0];
final float currentTranslateY = mTmpPosition[1];
final RecoverAnimation rv = new RecoverAnimation(prevSelected, animationType, prevActionState, currentTranslateX, currentTranslateY, targetTranslateX, targetTranslateY) {
@Override
public void onAnimationEnd(ValueAnimatorCompat animation) {
super.onAnimationEnd(animation);
if (this.mOverridden) {
return;
}
if (swipeDir <= 0) {
// this is a drag or failed swipe. recover immediately
mCallback.clearView(mRecyclerView, prevSelected);
// full cleanup will happen on onDrawOver
} else {
// wait until remove animation is complete.
mPendingCleanup.add(prevSelected.itemView);
mIsPendingCleanup = true;
if (swipeDir > 0) {
// Animation might be ended by other animators during a layout.
// We defer callback to avoid editing adapter during a layout.
postDispatchSwipe(this, swipeDir);
}
}
// removed from the list after it is drawn for the last time
if (mOverdrawChild == prevSelected.itemView) {
removeChildDrawingOrderCallbackIfNecessary(prevSelected.itemView);
}
}
};
final long duration = mCallback.getAnimationDuration(mRecyclerView, animationType, targetTranslateX - currentTranslateX, targetTranslateY - currentTranslateY);
rv.setDuration(duration);
mRecoverAnimations.add(rv);
rv.start();
preventLayout = true;
} else {
removeChildDrawingOrderCallbackIfNecessary(prevSelected.itemView);
mCallback.clearView(mRecyclerView, prevSelected);
}
mSelected = null;
}
if (selected != null) {
mSelectedFlags = (mCallback.getAbsoluteMovementFlags(mRecyclerView, selected) & actionStateMask) >> (mActionState * DIRECTION_FLAG_COUNT);
mSelectedStartX = selected.itemView.getLeft();
mSelectedStartY = selected.itemView.getTop();
mSelected = selected;
if (actionState == ACTION_STATE_DRAG) {
mSelected.itemView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
}
}
final ViewParent rvParent = mRecyclerView.getParent();
if (rvParent != null) {
rvParent.requestDisallowInterceptTouchEvent(mSelected != null);
}
if (!preventLayout) {
mRecyclerView.getLayoutManager().requestSimpleAnimationsInNextLayout();
}
mCallback.onSelectedChanged(mSelected, mActionState);
mRecyclerView.invalidate();
}
use of android.view.ViewParent in project Carbon by ZieIony.
the class ExpandableRecyclerView method dispatchTouchEvent.
@Override
public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
if (header != null && (getChildCount() == 0 || getChildAt(0).getTop() + getScrollY() > ev.getY()))
if (header.dispatchTouchEvent(ev))
return true;
switch(ev.getAction()) {
case MotionEvent.ACTION_MOVE:
float deltaY = prevY - ev.getY();
if (!drag && Math.abs(deltaY) > mTouchSlop) {
final ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
drag = true;
if (deltaY > 0) {
deltaY -= mTouchSlop;
} else {
deltaY += mTouchSlop;
}
}
if (drag) {
final int oldY = computeVerticalScrollOffset();
int range = computeVerticalScrollRange() - getHeight();
if (header != null)
range += header.getHeight();
boolean canOverscroll = overscrollMode == ViewCompat.OVER_SCROLL_ALWAYS || (overscrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0);
if (canOverscroll) {
float pulledToY = oldY + deltaY;
if (pulledToY < 0) {
topGlow.onPull(deltaY / getHeight(), ev.getX() / getWidth());
if (!bottomGlow.isFinished())
bottomGlow.onRelease();
} else if (pulledToY > range) {
bottomGlow.onPull(deltaY / getHeight(), 1.f - ev.getX() / getWidth());
if (!topGlow.isFinished())
topGlow.onRelease();
}
if (topGlow != null && (!topGlow.isFinished() || !bottomGlow.isFinished()))
postInvalidate();
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (drag) {
drag = false;
if (topGlow != null) {
topGlow.onRelease();
bottomGlow.onRelease();
}
}
break;
}
prevY = ev.getY();
return super.dispatchTouchEvent(ev);
}
use of android.view.ViewParent in project Carbon by ZieIony.
the class SeekBar method onTouchEvent.
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (radiusAnimator != null)
radiusAnimator.end();
radiusAnimator = ValueAnimator.ofFloat(thumbRadius, THUMB_RADIUS_DRAGGED);
radiusAnimator.setDuration(200);
radiusAnimator.setInterpolator(interpolator);
radiusAnimator.addUpdateListener(animation -> {
thumbRadius = (float) animation.getAnimatedValue();
postInvalidate();
});
radiusAnimator.start();
ViewParent parent = getParent();
if (parent != null)
parent.requestDisallowInterceptTouchEvent(true);
if (showLabel)
popup.show(this);
} else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
if (style == Style.Discrete) {
float val = (float) Math.floor((value - min + step / 2) / step) * step + min;
if (valueAnimator != null)
valueAnimator.cancel();
valueAnimator = ValueAnimator.ofFloat(value, val);
valueAnimator.setDuration(200);
valueAnimator.setInterpolator(interpolator);
valueAnimator.addUpdateListener(animation -> {
value = (float) animation.getAnimatedValue();
int thumbX = (int) ((value - min) / (max - min) * (getWidth() - getPaddingLeft() - getPaddingRight()) + getPaddingLeft());
int thumbY = getHeight() / 2;
int radius = rippleDrawable.getRadius();
rippleDrawable.setBounds(thumbX - radius, thumbY - radius, thumbX + radius, thumbY + radius);
postInvalidate();
});
valueAnimator.start();
}
if (radiusAnimator != null)
radiusAnimator.end();
radiusAnimator = ValueAnimator.ofFloat(thumbRadius, THUMB_RADIUS);
radiusAnimator.setDuration(200);
radiusAnimator.setInterpolator(interpolator);
radiusAnimator.addUpdateListener(animation -> {
thumbRadius = (float) animation.getAnimatedValue();
postInvalidate();
});
radiusAnimator.start();
ViewParent parent = getParent();
if (parent != null)
parent.requestDisallowInterceptTouchEvent(false);
if (showLabel)
popup.dismiss();
}
float v = (event.getX() - getPaddingLeft()) / (getWidth() - getPaddingLeft() - getPaddingRight());
v = Math.max(0, Math.min(v, 1));
float newValue = v * (max - min) + min;
int thumbX = (int) (v * (getWidth() - getPaddingLeft() - getPaddingRight()) + getPaddingLeft());
int thumbY = getHeight() / 2;
int radius = rippleDrawable.getRadius();
if (showLabel) {
int[] location = new int[2];
getLocationInWindow(location);
popup.setText(String.format(labelFormat, newValue));
popup.update(thumbX + location[0] - popup.getBubbleWidth() / 2, thumbY - radius + location[1] - popup.getHeight());
}
if (rippleDrawable != null) {
rippleDrawable.setHotspot(event.getX(), event.getY());
rippleDrawable.setBounds(thumbX - radius, thumbY - radius, thumbX + radius, thumbY + radius);
}
postInvalidate();
if (newValue != value && onValueChangedListener != null) {
if (style == Style.Discrete) {
int sv = stepValue(newValue);
if (stepValue(value) != sv)
onValueChangedListener.onValueChanged(this, sv);
} else {
onValueChangedListener.onValueChanged(this, newValue);
}
}
value = newValue;
super.onTouchEvent(event);
return true;
}
use of android.view.ViewParent in project Carbon by ZieIony.
the class HorizontalScrollView method dispatchTouchEvent.
@Override
public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
switch(ev.getAction()) {
case MotionEvent.ACTION_MOVE:
float deltaX = prevX - ev.getX();
if (!drag && Math.abs(deltaX) > mTouchSlop) {
final ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
drag = true;
if (deltaX > 0) {
deltaX -= mTouchSlop;
} else {
deltaX += mTouchSlop;
}
}
if (drag) {
final int oldX = getScrollX();
final int range = computeHorizontalScrollRange() - getWidth();
boolean canOverscroll = overscrollMode == OVER_SCROLL_ALWAYS || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0);
if (canOverscroll) {
float pulledToY = oldX + deltaX;
if (pulledToY < 0) {
leftGlow.onPull(deltaX / getWidth(), 1.f - ev.getY() / getHeight());
if (!rightGlow.isFinished())
rightGlow.onRelease();
} else if (pulledToY > range) {
rightGlow.onPull(deltaX / getWidth(), ev.getY() / getHeight());
if (!leftGlow.isFinished())
leftGlow.onRelease();
}
if (leftGlow != null && (!leftGlow.isFinished() || !rightGlow.isFinished()))
postInvalidate();
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (drag) {
drag = false;
if (leftGlow != null) {
leftGlow.onRelease();
rightGlow.onRelease();
}
}
break;
}
prevX = ev.getX();
return super.dispatchTouchEvent(ev);
}
Aggregations