ViewDragHelper 实现侧滑

    xiaoxiao2021-03-29  32

    ViewDragHelperde 侧滑的实现

    自定义View继承自RelativeLayout

    布局使用ListView 和 RecyclerView(如果继承FrameLayout会显示不全,必须继承RelativeLayout)

    布局中包含两个View 用include 导入

    <com.baima.swipedelete.SwipeDelete xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/swipeDelete" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <include layout="@layout/layout_content" /> <include layout="@layout/layout_delete"/> </com.baima.swipedelete.SwipeDelete>

    SwipeDelete类

    public class SwipeDelete extends RelativeLayout { private ViewDragHelper dragHelper; private View content; private View delete; private int deleteWidth; public SwipeDelete(Context context) { this(context, null); } public SwipeDelete(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SwipeDelete(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); dragHelper = ViewDragHelper.create(this, callback); } @Override protected void onFinishInflate() { super.onFinishInflate(); content = getChildAt(0); delete = getChildAt(1); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //获取宽和高 deleteWidth = delete.getMeasuredWidth(); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { content.layout(0, 0, content.getMeasuredWidth(), content.getMeasuredHeight()); delete.layout(content.getMeasuredWidth(), 0, content.getMeasuredWidth() + delete.getMeasuredWidth(), delete.getMeasuredHeight()); } //ViewDragHelper拦截事件 @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean result = dragHelper.shouldInterceptTouchEvent(ev); return result; } private float downX, downY; private long downTime; //自己消费事件 @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = event.getX(); downY = event.getY(); downTime = System.currentTimeMillis(); if (mlistener != null) { mlistener.onTouchDown(SwipeDelete.this); } break; case MotionEvent.ACTION_MOVE: float moveX = event.getX(); float moveY = event.getY(); //1.获取移动的dx和dy float dx = moveX - downX; float dy = moveY - downY; //2.判断谁大就是偏向于谁的方向 if (Math.abs(dx) > Math.abs(dy)) { //说明偏向于水平,我们就认为是想滑动条目,则请求listview不要拦截 requestDisallowInterceptTouchEvent(true); } break; case MotionEvent.ACTION_UP: //1.按下抬起的时间 long duration = System.currentTimeMillis() - downTime; //2.计算按下抬起的距离 float deltaX = event.getX() - downX; float deltaY = event.getY() - downY; float distance = (float) Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); //如果按下抬起的时间小于500,并且按下抬起的距离小于8像素,认为是满足了执行点击的条件 if (duration< ViewConfiguration.getLongPressTimeout()&&distance<ViewConfiguration.getTouchSlop()){ //作用就是执行OnClickListener的onClick方法 performClick(); } break; } dragHelper.processTouchEvent(event); return true; } private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() { @Override public boolean tryCaptureView(View child, int pointerId) { return true; } @Override public int getViewHorizontalDragRange(View child) { return 1; } @Override public int clampViewPositionHorizontal(View child, int left, int dx) { Log.e("222", "left=" + left); if (child == content) { left = getLeft(left); } else if (child == delete) { if (left < content.getMeasuredWidth() - delete.getMeasuredWidth()) { left = content.getMeasuredWidth() - delete.getMeasuredWidth(); } else if (left > content.getMeasuredWidth()) { left = content.getMeasuredWidth(); } } return left; } @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { super.onViewPositionChanged(changedView, left, top, dx, dy); if (changedView == content) { //让delete伴随移动 int newLeft = delete.getLeft() + dx; Log.e("tag", "getleft" + delete.getLeft() + "dx===" + dx); delete.layout(newLeft, 0, newLeft + delete.getMeasuredWidth(), delete.getBottom()); } else if (changedView == delete) { //让content伴随移动 int newLeft = content.getLeft() + dx; content.layout(newLeft, 0, newLeft + content.getMeasuredWidth(), content.getBottom()); } if (content.getLeft() == 0) { //关闭了content if (mlistener != null) { mlistener.close(SwipeDelete.this); } } else if (content.getLeft() == -delete.getMeasuredWidth()) { //打开了content if (mlistener != null) { mlistener.open(SwipeDelete.this); } } } //手指抬起的释放 @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { super.onViewReleased(releasedChild, xvel, yvel); if (content.getLeft() > -deleteWidth / 2) { //关闭 onClose(); } else { onOpen(); } } }; public void onOpen() { dragHelper.smoothSlideViewTo(content, -deleteWidth, 0); ViewCompat.postInvalidateOnAnimation(this); } public void onClose() { dragHelper.smoothSlideViewTo(content, 0, 0); ViewCompat.postInvalidateOnAnimation(this); } @Override public void computeScroll() { if (dragHelper.continueSettling(true)) { ViewCompat.postInvalidateOnAnimation(this); } } private int getLeft(int left) { if (left > 0) { left = 0; } else if (left < -delete.getMeasuredWidth()) { left = -delete.getMeasuredWidth(); } return left; } private OnSwipeDeleteListener mlistener; public void setOnSwipeDeleteListener(OnSwipeDeleteListener listener) { this.mlistener = listener; } public interface OnSwipeDeleteListener { void open(SwipeDelete swipe); void close(SwipeDelete swipe); void onTouchDown(SwipeDelete swipe); }

    Adapter实现这个类回调

    转载请注明原文地址: https://ju.6miu.com/read-664925.html

    最新回复(0)