package com.tigo.tankemao.ui.widget; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.Scroller; import java.util.List; import androidx.annotation.Nullable; /** * @author huangxiaohui * @date 2021/2/5 */ public class HorizontalInterruptView extends LinearLayout { public static final String TAG = "HorizontalInterruptView"; private List<View> changePaddingHorizontalViews = null; private float lastMoveX = 0f; private float currentMarginLeft = 0; private float minMargin = 0; private Scroller scroller; private VelocityTracker vt; public HorizontalInterruptView(Context context) { super(context); init(); } public HorizontalInterruptView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } private void init(){ scroller = new Scroller(getContext()); vt = VelocityTracker.obtain(); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean isInterrupt = false; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: if(!scroller.isFinished()) { scroller.abortAnimation(); } lastMoveX = ev.getX(); minMargin = (getWidth() - getInterrputViewsMaxWidth()); vt.clear(); vt.addMovement(ev); break; case MotionEvent.ACTION_MOVE: int scrollSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); int currentDx = (int)Math.abs(ev.getX() - lastMoveX); if(currentDx >= scrollSlop * 2) { isInterrupt = true; } break; } if(isInterrupt && minMargin < 0) { return true; } return super.onInterceptTouchEvent(ev); } private int getInterrputViewsMaxWidth() { if(changePaddingHorizontalViews == null) { return 0; } int maxWidth = 0; for (View changePaddingHorizontalView : changePaddingHorizontalViews) { maxWidth = Math.max(maxWidth, changePaddingHorizontalView.getWidth()); } return maxWidth; } @Override public boolean onTouchEvent(MotionEvent ev) { vt.addMovement(ev); switch (ev.getAction()) { case MotionEvent.ACTION_MOVE: if(changePaddingHorizontalViews != null) { for (View view : changePaddingHorizontalViews) { ViewGroup.LayoutParams lp = view.getLayoutParams(); if(lp instanceof MarginLayoutParams) { float dx = ev.getX() - lastMoveX; float temp = currentMarginLeft + dx; if(temp > 0) { temp = 0; }else if(temp < minMargin) { temp = minMargin; } MarginLayoutParams mlp = (MarginLayoutParams) lp; currentMarginLeft = temp; mlp.leftMargin = (int) currentMarginLeft; view.requestLayout(); lastMoveX = ev.getX(); } } } break; case MotionEvent.ACTION_UP: vt.computeCurrentVelocity(1000);//1000ms float velocity = vt.getXVelocity();//获取每1000ms移动的像素 if(Math.abs(velocity) > ViewConfiguration.get(getContext()).getScaledMinimumFlingVelocity()) { scroller.fling((int)currentMarginLeft, 0, (int)vt.getXVelocity(), 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0); postInvalidate(); } break; } return true; } public void setChangePaddingHorizontalViews(List<View> changePaddingHorizontalViews) { this.changePaddingHorizontalViews = changePaddingHorizontalViews; if(changePaddingHorizontalViews == null) { return; } for (View view : changePaddingHorizontalViews) { ViewGroup.LayoutParams lp = view.getLayoutParams(); if(lp instanceof MarginLayoutParams) { MarginLayoutParams mlp = (MarginLayoutParams) lp; mlp.leftMargin = (int) currentMarginLeft; view.requestLayout(); } } } @Override public void computeScroll() { if(scroller.computeScrollOffset()) { boolean isAbort = false; if(changePaddingHorizontalViews != null) { for (View view : changePaddingHorizontalViews) { ViewGroup.LayoutParams lp = view.getLayoutParams(); if (lp instanceof MarginLayoutParams) { MarginLayoutParams mlp = (MarginLayoutParams) lp; int temp = scroller.getCurrX(); if(temp > 0) { temp = 0; isAbort = true; }else if(temp < minMargin) { temp = (int)minMargin; isAbort = true; } currentMarginLeft = temp; mlp.leftMargin = (int) currentMarginLeft; view.requestLayout(); } } } if(isAbort) { scroller.abortAnimation(); }else{ postInvalidate(); } } } }
HorizontalInterruptView 实现监听水平滑动事件
最新推荐文章于 2023-03-16 11:33:50 发布