您的位置:首页 > 其它

定制视图与触摸事件

2015-09-23 22:47 337 查看
开发一个名为BoxDrawingView的定制View子类,响应用户的触摸与拖动,定制View将在屏幕上绘制出矩形框。效果如下:



BoxDrawingView.java

package com.example.draganddraw;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
* 尽管有着各式各样的定制视图,但仍可硬性将它们分为两大类别。 1、简单视图。简单视图可以有复杂的内部;之所以归为简单类别,是因为简单视图不包括子视图。
* 而且,简单视图几乎总是会执行定制绘制。 2、聚合视图。聚合视图由一些其他视图对象组成。聚合视图通常管理着子视图,但不负则执行定制绘制。
* 相反,图形绘制任务都委托给了各子视图。
*
* 以下为创建定制视图所需的三大步骤:
* 1、选择超类。对于简单定制视图而言,View是一个空白画布,因此是最常见的选择。而对于聚合定制视图,我们应该选择合适的布局类。
* 2、继承选定的超类,并至少覆盖一个超类构造方法。或者创建自己的构造方法,并在其中调用超类的构造方法。 3、覆盖其它关键方法,以定制视图行为。
*/
public class BoxDrawingView extends View {

private Box mCurrentBox;
private ArrayList<Box> mBoxs = new ArrayList<Box>();
private Paint mBoxPaint;
private Paint mBackgoundPaint;

/**
* 这里之所以添加两个构造方法,是因为视图可从代码或者布局文件实例化。从布局文件中实例化的视图可收到一个AttributeSet的实例,
* 该实例包含了XML布局文件中指定的XML属性。即使不打算使用构造方法,按习惯做法,我们也应该添加它们。
*/
public BoxDrawingView(Context context) {
this(context, null);
}

public BoxDrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
mBoxPaint = new Paint();
mBoxPaint.setColor(0x22ff0000);

mBackgoundPaint = new Paint();
mBackgoundPaint.setColor(0xfff7efe0);
}

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

canvas.drawPaint(mBackgoundPaint);

for (Box box : mBoxs) {
float left = Math.min(box.getOrigin().x, box.getCurrent().x);
float right = Math.max(box.getOrigin().x, box.getCurrent().x);
float top = Math.min(box.getOrigin().y, box.getCurrent().y);
float bottom = Math.max(box.getOrigin().y, box.getCurrent().y);

canvas.drawRect(left, top, right, bottom, mBoxPaint);
}
}

/**
* 该方法接受一个MotionEvent类实例,而MotionEvent类可用来描述包括位置和动作的触摸事件。动作则用来描述事件所处的阶段。
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
PointF curr = new PointF(event.getX(), event.getY());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mCurrentBox = new Box(curr);
mBoxs.add(mCurrentBox);
break;
case MotionEvent.ACTION_MOVE:
if(mCurrentBox != null){
mCurrentBox.setCurrent(curr);
invalidate();//该方法强制BoxDrawingView重新绘制自己。
}
break;
case MotionEvent.ACTION_UP:
mCurrentBox = null;
break;
case MotionEvent.ACTION_CANCEL:
mCurrentBox = null;
break;
}
return true;
}
}


MotionEvent动作常量

动作常量动作描述
ACTION_DOWN用户手指触摸到屏幕
ACTION_MOVE用户在屏幕上移动手指
ACTION_UP用户手指离开屏幕
ACTION_CANCEL父视图拦截了触摸事件
代码地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: