定制视图与触摸事件
2015-09-23 22:47
337 查看
开发一个名为BoxDrawingView的定制View子类,响应用户的触摸与拖动,定制View将在屏幕上绘制出矩形框。效果如下:
BoxDrawingView.java
MotionEvent动作常量
代码地址
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 | 父视图拦截了触摸事件 |
相关文章推荐
- iOS 动画之CALayer动画
- 工厂方法(FactoryMethod)
- TFTLCD的图片以及汉字字符显示说明
- 11 - 元组、集合和字典
- 数据库示例链接问题 无法连接到 (local)
- 命名空间的使用
- B-树
- 2015秋季个人阅读计划
- Matlab操作基础1
- POJ 1276 Cash Machine (多重背包转01背包优化)
- 阿里大幅度缩减校招 谁在撬动背后的奶酪?
- 【UIKit-124-9】#import <UIKit/UIView.h>
- mysql磁盘满时操作
- 内存对齐
- java设计模式第15弹--状态模式
- rpc框架之 avro 学习 2 - 高效的序列化
- 2015年秋季个人阅读计划
- C++ primer plus(sixth edition) 编程练习答案(answers for programing exercises)第九章(chapter 9) 1-4
- 顺序表
- 2015年秋季个人阅读计划