ViewDragHelper学习之九宫格拼图

家住魔仙堡 提交于 2021-02-15 09:36:16
import android.content.Context;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;

/**
 * Created by alanchen on 15/7/29.
 */
public class SwipeBackRelativelayout extends RelativeLayout {

    public static final String TAG = SwipeBackRelativelayout.class.getSimpleName();
    private ViewDragHelper mDragHelper;

    /*通过九个数字来表示空白格的位置
    * 1 2 3
    * 4 5 6
    * 7 8 9*/
    private int blank;

    private int maxLeft;
    private int maxTop;

    public SwipeBackRelativelayout(Context context) {
        this(context, null);
    }

    public SwipeBackRelativelayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        //初始化空白格的位置
        blank = 9;
        //ViewDragHelper是很好用的拖拽用设计,建议大家学习
        mDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelperCallback());
        //这句没用上
        mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mDragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mDragHelper.processTouchEvent(event);
        return true;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        /*会有8个带图片的控件在本ViewGroup里,不能多不能少,
        此处打上初始化标记,标记的意义参照变量blank*/
        for (int i = 0; i < 8; i++) {
            getChildAt(i).setTag(i + 1);
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        //获取max
        maxLeft = getChildAt(0).getWidth() * 2;
        maxTop = getChildAt(0).getHeight() * 2;
    }


    //Notice view 刚初始化的时候就会被调用一次
    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mDragHelper.continueSettling(true)) {
            invalidate();
        }
    }

    class ViewDragHelperCallback extends ViewDragHelper.Callback {
        //当前拖拽的view还在正位时候的位置
        public int curViewTop;
        public int curViewLeft;
        //当前拖拽的view的tag
        private int curDragView;

        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            //如果返回false,那么这个child是完全不会动的
            Log.v(TAG,"tryCaptureView");
            if (curDragView != 0)
                return (int) child.getTag() == curDragView;
            else {
                curDragView = (int) child.getTag();
                curViewLeft = child.getLeft();
                curViewTop = child.getTop();
                return true;
            }
        }

        @Override
        public void onEdgeTouched(int edgeFlags, int pointerId) {
            //好像跟setEdgeTrackingEnabled有关系,没用上
            Log.v(TAG,"onEdgeTouched");
        }

        @Override
        public int getViewHorizontalDragRange(View child) {
            return 1;
        }

        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            super.onViewPositionChanged(changedView, left, top, dx, dy);
        }

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
//                Log.d(TAG, "clampViewPositionHorizontal() called with  dx = [" + dx + "]");
            int c = (int) child.getTag();
            if (blank % 3 == 0) {
                if (c + 1 == blank) {
                    return mycalc(maxLeft, maxLeft / 2, left);
                }
            } else if (blank % 3 == 1) {
                if (c - 1 == blank) {
                    return mycalc(maxLeft / 2, 0, left);
                }
            } else {
                if (c + 1 == blank) {
                    return mycalc(maxLeft / 2, 0, left);
                } else if (c - 1 == blank) {
                    return mycalc(maxLeft, maxLeft / 2, left);
                }
            }
            return left - dx;
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            int c = (int) child.getTag();
            if (blank < 4) {
                if (c - 3 == blank) {
                    return mycalc(maxTop / 2, 0, top);
                }
            } else if (blank < 7) {
                if (c + 3 == blank) {
                    return mycalc(maxTop / 2, 0, top);
                } else if (c - 3 == blank) {
                    return mycalc(maxTop, maxTop / 2, top);
                }
            } else {
                if (c + 3 == blank) {
                    return mycalc(maxTop, maxTop / 2, top);
                }
            }
            return top - dy;
        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            Log.v(TAG, "onviewreleased");
            Log.v(TAG,curViewLeft+","+curViewTop);
            if (Math.abs(releasedChild.getLeft() - curViewLeft) == maxLeft / 2 || Math.abs(releasedChild.getTop() - curViewTop) == maxTop / 2) {
                Log.v(TAG, "onviewreleased in");
                int i = blank;
                blank = (int) releasedChild.getTag();
                releasedChild.setTag(i);
                curDragView = 0;
            } else if (releasedChild.getLeft() == curViewLeft && releasedChild.getTop() == curViewTop) {
                curDragView = 0;
            }
            Log.v(TAG,"curDragView:"+curDragView+",blank:"+blank);
        }

        int mycalc(int max, int min, int input) {
            return input > max ? max : input < min ? min : input;
        }

        @Override
        public void onViewCaptured(View capturedChild, int activePointerId) {
            Log.v(TAG,"onViewCaptured");
            super.onViewCaptured(capturedChild, activePointerId);
        }

        @Override
        public void onViewDragStateChanged(int state) {
            Log.v(TAG, "onViewDragStateChanged");
            super.onViewDragStateChanged(state);
            if (mDragHelper.getViewDragState() == ViewDragHelper.STATE_IDLE) {
                Log.v(TAG, "onviewdragstatechanged finish");
            }
        }
    }
}

以上就是主要代码,以下是布局文件相关

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/swipeackframelayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.inthecheesefactory.lab.designlibrary.Main2Activity">

    <com.inthecheesefactory.lab.designlibrary.SwipeBackRelativelayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true">

        <View
            android:id="@+id/view0"
            android:layout_width="180dp"
            android:layout_height="80dp"
            android:background="@drawable/header" />

        <View
            android:id="@+id/view8"
            android:layout_width="180dp"
            android:layout_height="80dp"
            android:layout_alignParentTop="true"
            android:layout_toEndOf="@+id/view0"
            android:layout_toRightOf="@+id/view0"
            android:background="@drawable/header" />

        <View
            android:id="@+id/view7"
            android:layout_width="180dp"
            android:layout_height="80dp"
            android:layout_alignParentTop="true"
            android:layout_toEndOf="@+id/view8"
            android:layout_toRightOf="@+id/view8"
            android:background="@drawable/header" />

        <View
            android:id="@+id/view6"
            android:layout_width="180dp"
            android:layout_height="80dp"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_below="@+id/view0"
            android:background="@drawable/header" />

        <View
            android:id="@+id/view5"
            android:layout_width="180dp"
            android:layout_height="80dp"
            android:layout_below="@+id/view0"
            android:layout_toEndOf="@+id/view0"
            android:layout_toRightOf="@+id/view0"
            android:background="@drawable/header" />

        <View
            android:id="@+id/view4"
            android:layout_width="180dp"
            android:layout_height="80dp"
            android:layout_below="@+id/view7"
            android:layout_toEndOf="@+id/view5"
            android:layout_toRightOf="@+id/view5"
            android:background="@drawable/header" />

        <View
            android:id="@+id/view3"
            android:layout_width="180dp"
            android:layout_height="80dp"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_below="@+id/view5"
            android:background="@drawable/header" />

        <View
            android:id="@+id/view2"
            android:layout_width="180dp"
            android:layout_height="80dp"
            android:layout_below="@+id/view5"
            android:layout_toEndOf="@+id/view3"
            android:layout_toRightOf="@+id/view3"
            android:background="@drawable/header" />

    </com.inthecheesefactory.lab.designlibrary.SwipeBackRelativelayout>

</RelativeLayout>

demo还没写完

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!