赞
踩
项目需要,涂鸦功能。但不仅仅需要其基础功能,需要在此基础上二次开发。
但Doodle的介绍相对比较简介,不深入研读、测试、修改不能了解其精髓。故而以记录此文,用于辅助理解代码,或有瑕疵或不对地方 望谅解。
本文主要从架构和代码层级:类函数角度分析代码。
Doodle 的git地址:https://github.com/1993hzw/Doodle
几篇不错的原理解析。
Android涂鸦画板原理详解——从初级到高级(一)_android涂鸦原理-CSDN博客
Android涂鸦画板原理详解——从初级到高级(二)_画画涂鸦游戏原理-CSDN博客
涂鸦框架的优化——解决绘制时的卡顿问题,纵享丝滑_flutter的gridview网格实现涂鸦很慢-CSDN博客
一、代码设计框架图:
三、Canvas drawText原理图
四、DoodleView代码分析
初始化调用方式
mDoodle = mDoodleView = new DoodleViewWrapper(this, bitmap, mDoodleParams.mOptimizeDrawing, new IDoodleListener() {...........}
IDoodleListener回调方法如下:
onSaved() 生成的图片保存等
onReady() 初始化设置、字体大小、颜色等
onError() 错误回调
ForegroundView //前景图层,每次刷新都会绘制,用于绘制正在创建或选中的item
绘制逻辑初步看为:items的遍历循环,然后执行drawAtTheTop ,此方法为画在所有item的上面 标注实则只有一个。在创建标注时添加addItem
BackgroundView // 背景图层,只在背景发生变化时绘制, 用于绘制原始图片或在优化绘制时的非编辑状态的item
Init()方法:参数bitmap(背景图片大小 这里可以限制住标注的图片大小范围)传入,对其与手机的屏幕宽高进行对比,并对图片居中显示,缩放率(屏幕相对图片的尺寸mCentreScale)、水平或垂直下的 图片距离屏幕边距长度mCentreTranX/Y、初始设置字体大小mSize(通过 屏幕分辨率(dp2px)/缩放率mCentreScale)
其他还封装了大量方法,用于处理:
将屏幕触摸坐标x转换成在图片中的坐标
将图片坐标x转换成屏幕触摸坐标
坐标换算
刷新界面refresh
.......
五、DoodleText代码分析:
父类子类之间嵌套关系
DoodleText extends DoodleRotatableItemBase extends DoodleSelectableItemBase extends DoodleItemBase implements IDoodleSelectableItem extends IDoodleItem
resetBounds 即 mRect(DoodleSelectableitemBase) 其内逻辑为 DoodleText实现子方法中重新获取size然后衡量text文字的矩形大小和偏移位置(offset(0,mRect.Height))
setLocation
resetBoundsScaled
doDraw(Canvas canvas):绘制文字、平移画布:根据mScale 和 文字的高度进行平移。
PointF mLocation用于记录 text的边框左顶点。
mPivotX, mPivotY用于记录text的文字中心坐标
变化标注位置:DoodleText.setLayout(x,y)
改变标注大小:DoodleText.setSize(会改变中心点 初始的时候设置一次就够了)
改变标注颜色:DoodleText.setColor()
toX/Y() 用于将屏幕触摸坐标x转换成在图片中的坐标
doDraw():此方法负责绘制文字
六、DoodleOnTouchGestureListener类解析:
手势监听器 对于手指滑动屏幕的方向增减:快速滑动和缓慢滑动,增减量是有差异
Adapter或者Activity初始化屏幕点击或滑动事件监听:
IDoodleTouchDetector detector = new DoodleTouchDetector(getApplicationContext(), mTouchGestureListener);
mDoodleView.setDefaultTouchDetector(detector);
mTouchGestureListener = new DoodleOnTouchGestureListener(mDoodleView, new DoodleOnTouchGestureListener.ISelectionListener() {.............}
onSelectedItem()回调IDoodleSelectableItem选中的状态变化。用于处理外部的界面UI变化
onScroll、onScrollEnd、onScrollBegin用于响应处理 涂鸦的画线
onScroll 处理移动操作,需先判断是否有选中item
mDoodle.setDoodleScale()用于为选中情况下 背景图片的缩放。
焦点改变后:双指触摸并移动图片进行平移:mDoodle.setDoodleTranslationX/Y()
onSingleTapUp 用于判断是否选中目标,从而显示或隐藏选中的边框。
其操作在DoodleText逻辑为 单击屏幕抬起后若无被选中且处于编辑状态回调onCreateSelectableItem, 执行createDoodleText(null,x,y) X,Y为转换后相对于图片的坐标
onScrollBegin:其内有关于旋转逻辑的判断:触摸点是否在旋转的范围内
双指缩放原理
DoodleOnTouchGestureListener 继承的父类TouchGestureDetector.OnTouchGestureListener
其中的onScale方法
为Doodle其他一个封装库 andorids 增量的增加和较少缩放比例值。初始1.0
额外封装的 源码 没有时间去研读了。原理待补充
七、DoodleRotatableItemBase类代码解析:
doDrawAtTheTop: 其内为绘制方框显示/隐藏 包括旋转的画线和小圈。
CanRotate(x,y): 用于判断是否触摸点 触摸到旋转的画线和小圈范围,此判断从DoodleOnTouchGestureListener的 onScrollBegin事件逻辑判断
八、DoodleItemBase类代码解析:
mScale 缩放倍数,围绕(PivotX,PivotY)旋转即中心值坐标,默认缩放值1.0f.控制画布的大小,即视觉上字体的大小。
draw(Canvas canvas) 处理旋转坐标、缩放、平移:
canvas.scale(mScale, mScale, px, py); // 缩放
这里自己加了限制逻辑,缩放过程中的左右和上下限制过界问题。
九、DoodleSelectableItemBase类代码解析:
ITEM_PADDING 绘制item矩形区域时增加的padding
getUnitSize(IDoodle) 获取当前涂鸦坐标系中的单位大小,该单位参考dp,独立于图片
limitBound 限定边界
Refresh() 用于DoodleView的 refresh实现,刷新前层view
十、涂鸦保存图片的逻辑:
业务逻辑层:mDoodle.save() DoodleView中执行save()方法。原理使用AsyncTask线程执行图片的绘制:refreshDoodleBitmap其内遍历所有的文字标注,分别执行draw()和 drawAtTheTop()(
十一、涂鸦指定的文字标注删除逻辑:
1.去除选中的item
mDoodle.removeItem(mTouchGestureListener.getSelectedItem());
方法执行到doodleView的 removeItem实现类:把分层的View内item删除。( 这些item绘制在View的画布上,而不是在图片Bitmap.比如正在创建或选中的item)
与此相关联>>新增方法:DoodleOnTouchGestureListener 的onRemoveSelectedItem 方法上传到最顶部调用处理,主要为删除item相关逻辑
2.设置选中的item为空
mTouchGestureListener.setSelectedItem(null);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。