您现在的位置是:亿华云 > 系统运维
2020征文-TV10分钟鸿蒙应用实战开发:鸿蒙手绘板 (含源代码)
亿华云2025-10-04 02:46:43【系统运维】8人已围观
简介想了解更多内容,请访问:和华为官方合作共建的鸿蒙技术社区https://harmonyos.51cto.com/#zz前言:今天是鸿蒙的手机beta发布活动,很荣幸受邀来到现场,一会儿可以给大家上个靓
想了解更多内容,征文请访问:
和华为官方合作共建的分钟鸿蒙技术社区
https://harmonyos.51cto.com/#zz
前言:

今天是鸿蒙的手机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变量,这里就需要用上了,整体上的原理就是,先把点击获得第一个点传入到曲线函数中,然后计算当前点击的位置加上第一个点的二分之一偏移量来细化得到一个更小的值来作为第三个参数,而第二个参数,我们让缓存的另一个点直接接收当前点击的点的值,然后传入到第二个参数中,最后又更新当前位置给第一个点,这样第一个点传入(旧的点),加上拖动后的当前点(新点),在当前点的二分偏移量的点,构成了三点传给了曲线函数,最后重新更新旧的点,让旧点变成一个新的位置,再次拖动的时候,就全部有了新的值,形成一个闭环。
invalidate()函数表示申请重新绘制(刷新UI)。
至此,我们就完成了点绘制(画笔)的计算方法。
下一步,我们要实现让画笔的这些点和线呈现到画板(Canvas)上:

追加实现Component.DrawTask的方法:
然后根据提示实现onDraw方法
在onDraw方法中添加如下实现:
canvas.drawPath(mPath, mPaint);
使用canvas的实例方法drawPath来将画笔和路径传入实现绘制。
到这里还没完,我们还需要做一些初始化的工作,我们写一个Init函数:
private void Init() { mPaint = new Paint(); mPaint.setColor(Color.WHITE); mPaint.setStrokeWidth(5f); mPaint.setStyle(Paint.Style.STROKE_STYLE); addDrawTask(this::onDraw); setTouchEventListener(this::onTouchEvent); }这里将画笔实例化,并设置颜色、粗细及样式。然后添加绘制任务addDrawTask、设置点击事件的监听setTouchEventListener,这俩函数分别是画布和事件监听内置的函数,并非自定义的。
最后,我们需要在Draw的构造函数中调用这个 Init()方法,这样就可以在使用new创建这个Draw组件实例时自动初始化。
(三)调用工具
最后时调用我们写的这个绘画工具。
回到slice目录,并打开MainAbilitySlice文件

定义各一个方向布局:
private DirectionalLayout directionalLayout = new DirectionalLayout(this);在onStart方法中,创建一个布局配置,并将配置指定给方向布局:
LayoutConfig config = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT); directionalLayout.setLayoutConfig(config);接着创建刚才写好的Draw组件,需要添加import com.qibiao.drawdemo.Draw;
Draw draw = new Draw(this);设置布局配置
draw.setLayoutConfig(config);创建背景元素(这里设置为黑色,黑板嚒~)
ShapeElement element = new ShapeElement(); element.setRgbColor(new RgbColor(0, 0, 0));设置背景元素
draw.setBackground(element);将组件添加到布局中
directionalLayout.addComponent(draw);设置UI内容:
super.setUIContent(directionalLayout);完整代码如下:
(四)运行效果
运行一个TV的远程模拟器,然后run:
手写一个:你好,鸿蒙

看起来还不错(别在意细节~)。
不过,还不够完美,我们再给他弄个擦除的功能。
回到Draw
添加一个重置的方法:

然后再到MainAbilitySlice中添加一个按钮,并调用clear方法:

再次运行已经支持擦除。
(五)完整代码
ok,本篇已经务必尽量精简了,最后放上代码链接(已开源):
https://gitee.com/doufx/draw-component
©著作权归作者和HarmonyOS技术社区共同所有,如需转载,请注明出处,否则将追究法律责任。
想了解更多内容,请访问:
和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com/#zz
很赞哦!(54339)
相关文章
- 小白注册网站域名该怎么办?有什么步骤?
- 新手怎么在选域名上省钱呢?有什么技巧?
- 怎样的域名别人容易搜寻?选域名的技巧要学会哪些?
- 为什么说域名对网站建设意义重大?新手要把握建站域名哪些?
- 旧域名的外链是否会对新建站点产生影响?
- 自己注册个人域名遇到难题怎么办?盘点个人域名注册问题
- 域名到期续费有啥可注意的?新手必知的域名续费问题
- 个人类型域名可以转换为企业类型?新手该如何做?
- 在数以亿计的网站中,我们应该抓住每一个可能带来宣传的机会,域名可以带有企业的名字,一般可以使用汉语拼音或者英语单词或者是相关缩写的形式,只要用户记住了你企业的名字,就能很容易的打出你的网站域名,同样的,记住了网站域名也能很快的记住你公司的名字。
- 新手怎么看待老域名的?老域名做网站有什么风险?
站长推荐
2、根据用户基础选择访问提供程序。由于互联问题的存在,接入商的选择也非常重要,如果用户群主要在联通,尽量选择联通接入较好的接入商,如果用户群主要在电信,那么选择电信接入较好的接入商。如果用户组位于国家/地区,则选择更好的访问提供程序进行交互。
新手遇到域名转入怎么做?该如何进行域名转入?
域名注册人要知道哪些权利和义务?应该做什么?
中文域名对企业来说怎样?具体有哪些好处?
比较短的域名方便用户记忆和传播,它带来的好处往往会超过其他类型的域名,如果你非要域名短而且还要包含关键词,那么往往会事与愿违,现在这种域名基本上是可遇而不可求的。
域名被骗频频发生?新手如何防止域名被骗?
看SEO站长如何选域名?有什么好的方法?
怎么做好域名投资?新手必须要注意这些