flutter 白板工具

Categories:

flutter

平常桌面上都放着一些草稿纸,因为经常要整理思路、画画草图啥的。这不是电子时代嘛,就觉得在手机、pad上也可以这样写写画画,我看了有很多这种类似的app,功能很简单就一个白板,直接就可以画,工具栏大概包括选画笔颜色、选笔尖大小、选橡皮擦等。

于是我用Flutter简单实现了一个,效果看下图,可以选颜色和笔尖大小:

主要思路

整体看这个功能实现不难,其实就是一个普通画板,画板我们可以用一个CustomPainter来做,关于CustomPainter我前面有文章有介绍过《Flutter 学习6:绘制动画》

CustomPainter 根据拖动手势,把手指滑动过的坐标画出来,其实就是把点连成线,并且得知道当时的画笔颜色和大小。

那拖动手势当然用GestureDetector啦,拖动的时候用onPanUpdate事件来获取坐标并且把坐标连成线,每次绘画结束就用拖动结束事件来处理onPanEnd

具体实现

Flutter一直在主推他的Material主题,跟Google他们自己的Android非常一致,这个主题还提供了很多Widget,给开发App提供了很多便利。但是Flutter官方其实还有一个IOS的主题cupertino,这次我就试着用这个cupertino主题开发这个白板工具。

cupertino主题

主题用法跟Material一样,MaterialApp对应这里用CupertinoAppScaffold对应这里用CupertinoPageScaffold。当然还有很多比如CupertinoThemeDataCupertinoNavigationBarCupertinoDialog等等,但是比起Material主题这里的Widget要少的多了。

  • CupertinoNavigationBar

  • CupertinoAlertDialog

  • CupertinoActionSheet

  • CupertinoPicker

  • CupertinoSegmentedControl

CustomPainter

前面思路中说过这里主要是画线,但是因为线条颜色、宽度有变化,所以必须的记录下当时的颜色和大小。于是我写了一个实体类来保存这些数据:

 class WPPainter {
Offset point;
Color color;
double strokeWidth;
WPPainter(this.point, this.color, this.strokeWidth);
}

然后CustomPainter处理绘画就简单了:

final List<WPPainter> points;

  @override
void paint(Canvas canvas, Size size) {
Paint paint = new Paint()..strokeCap = StrokeCap.round;
for (var i = 0; i < points.length - 1; i++) {
//null是线条结束标志
if (points[i] != null && points[i + 1] != null) {
var wp = points[i];
var nextWp = points[i + 1];
paint.color = wp.color;
paint.strokeWidth = wp.strokeWidth;
canvas.drawLine(wp.point, nextWp.point, paint);
}
}
} @override
bool shouldRepaint(_MyPainter oldDelegate) {
return oldDelegate.points != this.points;
}

上面代码注释说的线条结束标志就是前面思路中介绍的onPanEnd的时候,我们在points中添加一个null,这样就不会把所有的线都连起来了。

添加拖动事件:

onPanUpdate: (detail) {
//计算坐标
RenderBox referenceBox = context.findRenderObject();
Offset localPosition =
referenceBox.globalToLocal(detail.globalPosition大专栏  flutter 白板工具Twitter IconFacebook Icon"o">); setState(() {
//添加坐标
_points.add(WPPainter(
localPosition, _paintColor, _paintStokeWidth));
});
},
//结束标记
onPanEnd: (detail) => _points.add(null),

colorPicker颜色选择器

颜色选择器我这里是弹出一个Dialog,跟原来Material主题下一样,这里也提供了showDialog的方法,不过叫做:showCupertinoDialog

showCupertinoDialog(
context: context,
builder: (_) {
return CupertinoAlertDialog(
title: Text("选择颜色"),
content: ColorChooseWidget((color) {
_tempChooseColor = color;
}, selectedColor),
actions: <Widget>[
CupertinoDialogAction(
child: Text('取消'),
onPressed: () {
Navigator.of(context).pop();
},
),
CupertinoDialogAction(
child: Text('确定'),
isDefaultAction: true,
onPressed: () {
chooseColor(_tempChooseColor);
Navigator.of(context).pop();
},
)
],
);
},
);

弹出的Dialog内容ColorChooseWidget就是一个GridView 。这里的GridView我本来想根据屏幕大小控制Dialog宽度,然后根据宽度计算GridViewcrossAxisCount就是一行放几个颜色。但是后来发现原来CupertinoAlertDialog的宽度是固定死的270

最新文章

  1. C#进阶系列——MEF实现设计上的“松耦合”(二)
  2. 完全卸载Oracle11G
  3. Canvas 内部元素添加事件处理
  4. Kinect SDK 安装失败
  5. ORACLE PL/SQL编程详解
  6. dom4j创建xml
  7. js中模仿接口继承
  8. SqlServer建表规范
  9. nginx 偶发 403原因
  10. Lua 笔记
  11. iis7 发布mvc3 遇到的HTTP错误 403.14-Forbidden Web 服务器被配置为不列出此目录的内容及Login on failed for &quot;IIS APPPOOL\ASP.NET v4.0&quot;问题
  12. 关于promise
  13. 优化MYSQL FILESORT
  14. 使用最新的log4cplus(1.1.1)隔离不同的 log 文件输出
  15. hibernate 配置文件
  16. shiro真正项目中的实战应用核心代码!!!
  17. RSA签名和验签Util
  18. 深入理解Spring Redis的使用 (三)、使用RedisTemplate的操作类访问Redis
  19. git使用备注
  20. Android 安全退出应用程序的方法总结

热门文章

  1. 4.docker 简介
  2. C# 查找其他应用程序并打开、显示、隐藏、关闭的API
  3. Opencv笔记(四)——绘图函数
  4. 解决安装 .net framework 发生 extracting files error 问题
  5. [JSOI2019]神经网络(树形DP+容斥+生成函数)
  6. Codeforces Round #556(Div.1)
  7. 七种常见经典排序算法总结(C++实现)
  8. ionic3 发布订阅者模式实现
  9. linux特殊权限(acl)
  10. idea出现 Unable to open debugger port (127.0.0.1:xxxx): java.net.SocketException &quot;socket closed&quot; 解决方案