目录:
前言
创建项目
实现绘画工具
调用工具
运行效果
完整代码
前言:
今天是鸿蒙的手机beta发布活动,很荣幸受邀来到现场,一会儿可以给大家上个靓照~。
本篇旨在通过实践一些样例,让开发者们快速提高肾上腺素,欢乐的加入鸿蒙应用开发之旅。整篇就是一个完整的实操样例,我也尽量在一片中把内容都讲清楚。
基础的一些知识点,可以访问我另一个系列:《鸿蒙OS应用开发实践》
正文
(一)创建项目
1.创建一个新的TV项目:
2.创建一个新的Java类:
命名为Draw:
这个作为我们的绘画的核心组件,所以我们让他继承Component,方便后面的调用。需要注意的是,这里导入包名的时候,我们选择第一个:ohos.agp.components包。
完成后,依然会报错,提示我们需要创建构造函数:
同样默认会有很多构造方法,我们选择第一个(单个参数)即可。
(二)实现绘画工具
这样一个基础的组件类就创建好了,接着我们构思下一画板工具里需要哪些元素:
画笔:用于画出各种点和线。
画板:用于展现我们到底花了什么,它是内容的载体。
所以,根据以上这些元素,在接下来我们需要在代码里定义和创建一些内容:
Path mPath = new Path();
Paint mPaint;
Point mPrePoint = new Point();
Point mPreCtrlPoint = new Point();
Canvas : 画布的意思,属于渲染组件,一般用于渲染各种界面元素,这里需要 import ohos.agp.render.Canvas;包
Path : 路径的意思,也属于渲染组件,用于描述绘制的路径。需要import ohos.agp.render.Path;
Paint : 表示绘制,属于渲染组件,用于一些绘制操作,需要import ohos.agp.render.Paint;
Point : 表示一个点,通常由二维坐标(x,y)组成,需要import ohos.agp.utils.Point;
所以上面的代码,我们先定义了一些等待使用的工具变量。
现在我们缺少了一个东西,那就是如何交互?一般的,绘图这样的,我们要么鼠标,要么触屏,要么就是电子绘笔等。这里我们使用鸿蒙触摸组件来实现。
在代码中去实现Component.TouchEventListener方法:
实现onTouchEvent()方法:
onTouchEvent包含两个参数:Component表示当前接收的组件,TouchEvent表示当前的触摸事件。
通过getAction实例方法可以获取TouchEvent的状态:
TouchEvent.PRIMARY_POINT_DOWN : 按下状态
TouchEvent.PRIMARY_POINT_UP :点按状态抬起
TouchEvent.POINT_MOVE: 点按拖动
我们需要在按下的时候开始记录点的位置,拖动的时候记录下整个轨迹,而抬起的时候则不做任何事情。
所以,在onTouchEvent事件函数中,我们的代码这样写:
switch (touchEvent.getAction()) {
case TouchEvent.PRIMARY_POINT_DOWN: {
MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());
mPath.moveTo(point.getX(), point.getY());
mPrePoint.position[0] = point.getX();
mPrePoint.position[1] = point.getY();
mPreCtrlPoint.position[0] = point.getX();
mPreCtrlPoint.position[1] = point.getY();
return true;
}
case TouchEvent.PRIMARY_POINT_UP:
break;
case TouchEvent.POINT_MOVE: {
break;
}
MmiPoint :表示是人机交互接口的一个Point,这里用来接收点击事件的点,需要import ohos.multimodalinput.event.MmiPoint;
然后在点击下去的这一下,指定路径mPath的moveTo目标为当前事件点击获得的点。
同时也设置了两个预制缓存点的坐标为当前点击的点。
抬起的操作,我们这里暂时不做处理。
直接来处理下移动分支下的操作:
case TouchEvent.POINT_MOVE: {
MmiPoint point = touchEvent.getPointerPosition(touchEvent.getIndex());
Point currCtrlPoint = new Point((point.getX() + mPrePoint.position[0]) / 2,
(point.getY() + mPrePoint.position[1]) / 2);
mPath.cubicTo(mPrePoint, mPreCtrlPoint, currCtrlPoint);
mPreCtrlPoint.position[0] = currCtrlPoint.position[0];
mPreCtrlPoint.position[1] = currCtrlPoint.position[1];
mPrePoint.position[0] = point.getX();
mPrePoint.position[1] = point.getY();
invalidate();
break;
解析:
同样用MmiPoint来接收点击输入,然后先说下mPath.cubicTo:使用path的cubicTo方法来实现三次贝塞尔曲线,就是说两个点之间的线有两个控制点。这样可以让曲线更加的平滑,它需要输入三个点的参数,所以,我们之前定义了两个Point变量,这里就需要用上了,整体上的原理就是,先把点击获得第一个点传入到曲线函数中,然后计算当前点击的位置加上第一个点的二分之一偏移量来细化得到一个更小的值来作为第三个参数,而第二个参数,我们让缓存的另一个点直接接收当前点击的点的值,然后传入到第二个参数中,最后又更新当前位置给第一个点,这样第一个点传入(旧的点),加上拖动后的当前点(新点),在当前点的二分偏移量的点,构成了三点传给了曲线函数,最后重新更新旧的点,让旧点变成一个新的位置,再次拖动的时候,就全部有了新的值,形成一个闭环。
作者:涂启标
想了解更多内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com/#bky