带你撸一个好玩的涂鸦View

今日科技快讯

昨日阿里巴巴公布了截至6月30日的2017财年第一财季财报。报告显示,公司该季度营收为人民币501.84亿元,同比增长56%;按美国通用会计准则计(GAAP),净利润为人民币140.31亿元,去年同期为净利润人民币71.42亿元,同比增长96%;合摊薄后每股利润为人民币5.65元,去年同期为每股利润人民币2.94元,同比增长92%。

作者简介

明天就是周末啦,提前祝大家周末愉快!

本篇是 developerHaoz 的第二篇投稿,分享了一个可涂鸦的自定义View,希望大家喜欢!

developerHaoz 的博客地址:

http://www.jianshu.com/u/09ef3072029d

前言

最近项目中需要用到涂鸦的功能,在 Github 上搜了一圈也没找到适合的库,索性就自己撸一个出来,正好复习一下自定义 View 的知识。写完之后怎么可以自己藏着呢,当然得写篇博客分享给大家。

在开始本文的内容之前,先展示一波最终的效果:

可以看到这个这个自定义 View 的功能还是很丰富的,无论是设置画笔的形状、颜色、粗细,还是进行重置和保存,该有的 API,基本都已经实现了。

定义画笔的行为类

这里所说的「行为」指的就是我们刚才看到的画笔的形状,无论是路径、直线、还是圆形,这些东西说到底都是画笔的行为。

所以我们先定义一个公共的父类,以便进行管理,减少代码量。

可以看到这个类被定义成抽象类,里面有 draw() 和 move() 两个抽象方法,这两个方法就是留给子类进行继承和拓展的,子类只要实现这两个方法,确定好他们各自的行为,就能让画笔显示出各种各样的效果。

接下来举几个具体的子类来说明一下用法:

就拿最常见的自由曲线来作为例子讲一下。我们定义 MyPath 这个类,继承自 BaseAction,然后添加了 Path 和 size 两个成员变量。其中的 size 是用来设置画笔的粗细。Path 是用来确定自由曲线的轨迹。

在 MyPath 的 draw() 方法中我们创建了一个 Paint 用于图形的描绘。最后将 path 和 paint 传给 canvas,实现图形的最终绘制。

其他子类都是按照这种思路来实现。

实现自定义DoodleView

这个 DoodleView 是直接继承 SurfaceView 的。本来想继承 View 来写,后来仔细想了下最后还是用 SurfaceView 来进行实现。

这里简单说一下 View 和 SurfaceView 的区别。

  • View 在主线程中对页面进行刷新,而 SurfaceView 则是另外开了一个子线程对当前页面进行刷新。

  • View 适合用于主动更新的情况,而 SurfaceView 则适用于被动更新的情况,比如频繁刷新界面。

因为我们这个涂鸦的 View,是频繁进行刷新的,每次触摸屏幕都会进行相应的界面刷新,所以用 SurfaceView 来实现就比较合理了。

这里我直接结合代码来讲一下 DoodleView 的实现思路,因为我是继承自 SurfaceView 来写的,对于 SurfaceView 不是很了解的朋友,可以先看一下这篇文章

Android中的SurfaceView详解

http://www.jianshu.com/p/b037249e6d31

可以看到,我们先定义了一个枚举类,用于区分各种画笔的形状,为了让代码看起来更简洁,我这里只放了 Path 和 Line 两种类型的,如果你还想实现其他类型的形状,直接加进去就行了。

在类的一开始我们定义了一些必要的成员变量,如画笔的颜色、形状、粗细,以及保存画笔行为的 List<BaseAction>,以及需要用到的画笔 Paint

准备工作搞定了之后就开始进行核心代码的实现了。

构造函数

可以看到我们在构造函数中的调用了 init() 方法,先进行了 SurfaceHolder 的一些设置,以及对 Paint 进行了必要的设置。

然后在 surfaceCreated(SurfaceHolder holder) 方法中对 Canas 进行了创建和提交,以及初始化了 List<BaseAction>

触摸事件的处理

这个方法的实现可以说是这个 DoodleView 的核心了

我们先拿到触摸的横坐标和纵坐标,然后根据手势来进行相应的处理

  • ACTION_DOWN:当刚开始出触摸屏幕的时候,先设置画笔的形状

  • ACTION_MOVE:手开始移动的时候,调用 move() 和 draw() 对 Canvas 进行绘制,最后将 Canvas 的内容进行提交。

  • ACTION_UP:将手抬起来的时候,将当前画笔的形状添加到 List<BaseAction> 中,并将 curAction(当前的画笔形状)设为 null.

其他的API

除了一些核心方法的实现,为了拓展这个 DoodleView 的功能,我还添加了一些实用的 API。

  • 保存涂鸦后的图片

先创建一个用于保存图片的路径,判断路径是否存在,如果不存在的话,就创建一下。否则通过这个路径拿到对应的文件流,并将当前图片转换成 Bitmap 之后放进去。

  • 重置涂鸦的界面

我们进行涂鸦,难免会出现手误,这时候进行重置就显得相当重要了。

这里直接获取 Canvas,然后将 List<BaseAction> 进行 clear,因为 List<BaseAction> 里面没有内容,Canvas 上自然也就没有任何东西,最后将 Canvas 进行提交。

以上便是本文的全部内容,有兴趣的同学可以看一下具体实现:

https://github.com/developerHaoz/DoodleView

更多

每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。

如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。

欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值