文档章节

ViewDragHelper学习之九宫格拼图

流花哥哥
 流花哥哥
发布于 2015/09/24 15:39
字数 946
阅读 21
收藏 1
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还没写完

© 著作权归作者所有

流花哥哥
粉丝 1
博文 8
码字总数 2015
作品 0
汕头
程序员
私信 提问
【HDU - 1043】Eight(反向bfs+康托展开)

Eight Descriptions: 简单介绍一下八数码问题: 在一个3×3的九宫格上,填有1~8八个数字,空余一个位置,例如下图: 1 2 3 4 5 6 7 8 在上图中,由于右下角位置是空的,你可以移动数字,比如...

Sky丨Star
07/19
0
0
JAVA代码—算法基础:数独问题(Sodoku Puzzles)

数独问题(Sodoku Puzzles) 数独游戏(日语:数独 すうどく)是一种源自18世纪末的瑞士的游戏,后在美国发展、并在日本得以发扬光大的数学智力拼图游戏。 拼图是九宫格(即3格宽×3格高)的...

seagal890
2018/03/24
0
0
【开发教程】HTML5网页内的视频拼图特效-源码吐血分享

前几天那谁发布的《月熊志》那个网站,我对里面的视频拼图这个效果很感兴趣。琢磨好几天,终于搞定了,并且知道是怎么做出来的了,在这里分享给大家。 大家先去这个网站看效果(网址:http:...

大鹦鹉
2013/12/27
1K
2
数独完全解生成-分组轮转算法

数独(日语:数独すうどく)是一种源自18世纪末的瑞士,后在美国发展、并在日本得以发扬光大的数学智力拼图游戏。拼图是九宫格(即3格宽×3格高)的正方形状,每一格又细分为一个九宫格。在每...

9plus
2017/11/12
0
0
[deviceone开发]-拼图小游戏

一、简介 九宫格小游戏,可从本地图库载入一张图片,填充到9个ImageView,另涉及Timer计时、图库控件。 每个格子都是相同的控件,动态添加到首页中的,在初始化后,响应touch事件,之后通过多...

DoProject
2016/10/28
104
0

没有更多内容

加载失败,请刷新页面

加载更多

分页查询

一、配置 /*** @author beth* @data 2019-10-14 20:01*/@Configurationpublic class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor(){ ......

一个yuanbeth
22分钟前
2
0
在LINQPad中使用Ignite.NET

LINQPad是进行.NET开发的一款优秀工具,非常有利于Ignite.NET API的快速入门。 入门 下载LINQPad:linqpad.net/Download.aspx,注意要选择64位操作系统的AnyCPU版本; 安装Ignite.NET的NuGet...

李玉珏
35分钟前
3
0
JS其他类型值转化为Boolean类型规则

本文转载于:专业的前端网站➤JS其他类型值转化为Boolean类型规则 由于最近在笔试的时候,发现好多关于其他类型转化为Boolean类型的题目,因此总结一下! 一、String类型转化为Boolean 1.转化...

前端老手
46分钟前
5
0
EurekaClient自动装配及启动流程解析

在上篇文章中,我们简单介绍了EurekaServer自动装配及启动流程解析,本篇文章则继续研究EurekaClient的相关代码 老规矩,先看spring.factories文件,其中引入了一个配置类EurekaDiscoveryClie...

Java学习录
52分钟前
9
0
析构函数是否必须为虚函数?为何?

p517 在C++中,基类指针可以指向一个派生类的对象。如果基类的析构函数不是虚函数,当需要delete这个指向派生类的基类指针时,就只会调用基类的析构函数,而派生类的析构函数无法被调用。容易...

天王盖地虎626
53分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部