【Android】自定义view-拖动小球移动

简介: Android应用界面中可以看得见的都是由一个个的View所组成的,几乎所有的可视的控件都是基于View写的。在View中提供了对touch也就是手势的捕获和传递,我们可以对View里面手势的重写来达到我们所需要的特性。比如说我们现在要做一款游戏,内容很简单,就是要实现让如图所示的一个黑色的小球在根据手指移动而在手机屏幕内移动。 我们可以重写View里面的public boolean

Android应用界面中可以看得见的都是由一个个的View所组成的,几乎所有的可视的控件都是基于View写的。在View中提供了对touch也就是手势的捕获和传递,我们可以对View里面手势的重写来达到我们所需要的特性。比如说我们现在要做一款游戏,内容很简单,就是要实现让如图所示的一个黑色的小球在根据手指移动而在手机屏幕内移动。

我们可以重写View里面的public boolean onTouchEvent(MotionEvent event)方法,来获取到所有的手势操作,再从中选择出所需要的手势进行操作。

所以可以得到如下的一段代码:

/**
 * Created by obo on 15/8/21.
 */
public class TouchView extends View{

    public static String TAG = TouchView.class.getCanonicalName();
    //当前小球的位置
    private PointF currrentPosition = new PointF(100,100);
    //手指触摸起点坐标
    private PointF moveStartPosition = new PointF(0,0);
    //当前手指位置坐标
    private PointF moveEndPosition = new PointF(0,0);

    private Context context;

    public TouchView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    @Override
    public void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        canvas.drawCircle(currrentPosition.x + (moveEndPosition.x - moveStartPosition.x),currrentPosition.y+(moveEndPosition.y - moveStartPosition.y),50,new Paint());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getActionMasked())
        {
            case MotionEvent.ACTION_DOWN:
                moveStartPosition.x = event.getX();
                moveStartPosition.y = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                moveEndPosition.x = event.getX();
                moveEndPosition.y = event.getY();
                //刷新
                this.postInvalidate();
                break;

            case MotionEvent.ACTION_UP:
                currrentPosition.x += (moveEndPosition.x - moveStartPosition.x);
                currrentPosition.y += (moveEndPosition.y - moveStartPosition.y);
                moveStartPosition.x = moveEndPosition.x;
                moveStartPosition.y = moveEndPosition.y;
                break;
            default:
        }
        return true;
    }
}


可以看到当前onTouchEvent方法返回ture,表明这个View是要对当前手势操作进行捕获的,这里包括 按下、移动和抬起等相关操作,如果返回的是false的话,只会接收到第一次的一个ACTION_DOWN也就是按下的响应,之后的移动手势和抬起的手势都无法获取到。

方法onTouchEvent里面做了三件事情:1.当用户手指按下的时候,初始化记录下开始按下的坐标,并立即返回不需要刷新界面。2.当用户移动手指的时候,记录用户手指的位置,并且重新刷新界面。3.当用户退出手势也就是抬起手指的时候,将位移赋值给基础坐标点,并让手势起点坐标和手势终点坐标x、y相等(清零)。

而如果使用Matrix的话将会使整个过程变得更加简单,只需要事先得到小球的bitmap就能使用matrix对小球进行包括 位移、形变、旋转在内的变换,这里只使用matrix的位移变换效果,具体实现代码如下:

/**
 * Created by obo on 15/8/26.
 */
public class MatrixView extends View {

    public final static String TAG = MatrixView.class.getCanonicalName();
    //bitmap运行矩阵
    Matrix matrix = new Matrix();
    //记录点
    PointF startPoint = new PointF();
    //自定义bitmap
    Bitmap bitmap = Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888);

    public MatrixView(Context context, AttributeSet attrs) {
        super(context, attrs);

        Canvas canvas = new Canvas(bitmap);
        //直接在bitmap上面绘制一个小球
        canvas.drawCircle(50,50,50,new Paint());
    }

    @Override
    public void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);

        canvas.drawBitmap(bitmap, matrix, new Paint());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        super.onTouchEvent(event);

        if (event.getActionMasked() == MotionEvent.ACTION_MOVE)
        {
            matrix.postTranslate(event.getX() - startPoint.x, event.getY() - startPoint.y );
            //刷新
            this.postInvalidate();
        }

        startPoint.x = event.getX();
        startPoint.y = event.getY();

        return true;

    }
}

这一块的代码实现的效果和先前的一样,增加了Matrix变量,少了一个PointF变量,同时在onTouchEvent和onDraw方法中的代码量也降低了一些。Matrix其实是一个3X3的矩阵,使用Matrix可以一步步积累变换的操作,无论对matrix操作多少次,其对图片的处理复杂度都是固定不变的,并且能对图片进行快速的变换,这就是使用matrix的带来的好处。


目录
相关文章
|
18天前
|
Java API 调度
Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播
Android系统 自定义开机广播,禁止后台服务,运行手动安装应用接收开机广播
41 0
|
18天前
|
存储 Java Linux
Android Mstar增加IR 自定义遥控头码完整调试过程
Android Mstar增加IR 自定义遥控头码完整调试过程
27 1
|
1天前
|
XML Android开发 数据格式
Android下自定义Button样式
Android下自定义Button样式
|
1天前
|
XML Java Android开发
如何美化android程序:自定义ListView背景
如何美化android程序:自定义ListView背景
|
1天前
|
搜索推荐 Android开发
自定义Android标题栏TitleBar布局
自定义Android标题栏TitleBar布局
|
4天前
|
Android开发
Android SystemUI去掉拖动亮度条QSPanel界面隐藏功能
Android SystemUI去掉拖动亮度条QSPanel界面隐藏功能
7 0
|
18天前
|
Android开发 芯片
Android源代码定制:移除无用lunch|新建lunch|自定义customize.mk
Android源代码定制:移除无用lunch|新建lunch|自定义customize.mk
26 3
|
18天前
|
移动开发 Java Unix
Android系统 自动加载自定义JAR文件
Android系统 自动加载自定义JAR文件
40 1
|
18天前
|
Shell Android开发 开发者
Android系统 自定义动态修改init.custom.rc
Android系统 自定义动态修改init.custom.rc
34 0
|
18天前
|
存储 安全 Android开发
Android系统 自定义系统和应用权限
Android系统 自定义系统和应用权限
29 0