【Flutter 专题】33 自定义 View 之 Paint

Flutter 提供了与 Android 相似的 PaintCanvas 来实现自定义 View,使应用更方便完善。和尚尝试学习和使用自定义 View

自定义 View 包括 Paint 画笔与 Canvas 画布,两部分缺一不可;两者通过 CustomPainter 衔接使用。需要实现 paint() 绘制方法与 shouldRepaint() 在刷新布局的时是否需要重绘。

class PaintCustom extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

Paint 画笔

Paint 画笔有很多属性,和尚介绍如下常用属性;和尚以一条线和一个圆来测试。一目了然的属性和尚就暂且略过,主要尝试其他属性。

color -> 画笔颜色
strokeWidth -> 画笔粗细
isAntiAlias -> 是否抗锯齿
filterQuality -> 颜色渲染模式质量:高 / 中 / 低
shader -> 着色器,一般用来绘制渐变效果或 ImageShader
strokeCap -> 笔触线帽类型:round / butt / square

笔触类型包括三种,默认为 butt 即从初始点到终止点;square 在初试点与终止点绘制一个方块;round 即在初试点与终止点绘制一个圆角;

canvas.drawLine(
    Offset(30.0, 30.0), Offset(Screen.width - 30.0, 30.0), Paint());
canvas.drawLine(
    Offset(30.0, 60.0), Offset(Screen.width - 30.0, 60.0), Paint()..strokeWidth = 8.0..isAntiAlias = true);
canvas.drawLine(
    Offset(30.0, 120.0), Offset(Screen.width - 30.0, 120.0), Paint() ..strokeWidth = 8.0 ..isAntiAlias = true..strokeCap = StrokeCap.round);
canvas.drawLine(
    Offset(30.0, 90.0), Offset(Screen.width - 30.0, 90.0), Paint()..strokeWidth = 8.0..isAntiAlias = true..strokeCap = StrokeCap.square);

如图:

strokeJoin -> 线结合处:锐角 / 圆弧 / 直线

在线的交汇点处,可以设置交叠时样式,包括:锐角,圆弧和直角样式,官方效果更直接。

style -> 画笔样式:填充 / 描边

style 包括两种样式,默认 PaintingStyle.fill 为填充,PaintingStyle.stroke 为描边;用圆来绘制效果更明显;

canvas.drawCircle(Offset(100.0, 200.0), 50.0, Paint()..strokeWidth = 8.0);
canvas.drawCircle(Offset(260.0, 200.0), 50.0, Paint()..strokeWidth = 8.0..style = PaintingStyle.stroke);

如图:

maskFilter -> 模糊遮照效果

模糊效果包括:nomal 内外模糊;solid 内部填充外边模糊,类似于荧光灯效果;outer 内部透明外边模糊;inner 内部模糊,外边正常;和尚建议大家多尝试效果;

canvas.drawLine(Offset(30.0, 280.0), Offset(Screen.width - 30.0, 280.0),
    Paint()..strokeWidth = 8.0..strokeCap = StrokeCap.round..maskFilter = MaskFilter.blur(BlurStyle.normal, 3.0));
canvas.drawLine(Offset(30.0, 310.0), Offset(Screen.width - 30.0, 310.0),
    Paint()..strokeWidth = 8.0..strokeCap = StrokeCap.round..maskFilter = MaskFilter.blur(BlurStyle.outer, 3.0));
canvas.drawLine(Offset(30.0, 340.0), Offset(Screen.width - 30.0, 340.0),
    Paint()..strokeWidth = 8.0..strokeCap = StrokeCap.round..maskFilter = MaskFilter.blur(BlurStyle.solid, 3.0));
canvas.drawLine(Offset(30.0, 370.0), Offset(Screen.width - 30.0, 370.0),
    Paint()..strokeWidth = 8.0..strokeCap = StrokeCap.round..maskFilter = MaskFilter.blur(BlurStyle.inner, 3.0));

如图:

blendMode -> 颜色混合模式,类型很多
colorFilter -> 颜色渲染模式,一般是矩阵效果来改变

颜色混合与颜色渲染是两个很神奇的属性,可以通过众多模式调整颜色叠加效果,并与背景色衔接,和尚还无法准确的说明其中叠加的原理;

canvas.drawLine(Offset(30.0, 400.0), Offset(Screen.width - 30.0, 400.0),
    Paint()..strokeWidth = 8.0..blendMode = BlendMode.exclusion..colorFilter = ColorFilter.mode(Colors.white, BlendMode.exclusion));
canvas.drawLine(Offset(30.0, 430.0), Offset(Screen.width - 30.0, 430.0),
    Paint()..strokeWidth = 8.0..blendMode = BlendMode.exclusion..colorFilter = ColorFilter.mode(Colors.yellow, BlendMode.exclusion));
canvas.drawLine(Offset(30.0, 460.0), Offset(Screen.width - 30.0, 460.0),
    Paint()..strokeWidth = 8.0..blendMode = BlendMode.exclusion..colorFilter = ColorFilter.mode(Colors.red, BlendMode.exclusion));
canvas.drawLine(Offset(30.0, 490.0), Offset(Screen.width - 30.0, 490.0),
    Paint()..strokeWidth = 8.0..blendMode = BlendMode.exclusion..colorFilter = ColorFilter.mode(Colors.green, BlendMode.exclusion));

如图:


和尚对自定义 View 的了解还并不深入,有很多需要继续学习研究的东西,如有问题,请多多指教!如下是和尚公众号,欢迎闲来吐槽~ Flutter 提供了与 Android 相似的 PaintCanvas 来实现自定义 View,使应用更方便完善。和尚尝试学习和使用自定义 View

自定义 View 包括 Paint 画笔与 Canvas 画布,两部分缺一不可;两者通过 CustomPainter 衔接使用。需要实现 paint() 绘制方法与 shouldRepaint() 在刷新布局的时是否需要重绘。

class PaintCustom extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

Paint 画笔

Paint 画笔有很多属性,和尚介绍如下常用属性;和尚以一条线和一个圆来测试。一目了然的属性和尚就暂且略过,主要尝试其他属性。

color -> 画笔颜色
strokeWidth -> 画笔粗细
isAntiAlias -> 是否抗锯齿
filterQuality -> 颜色渲染模式质量:高 / 中 / 低
shader -> 着色器,一般用来绘制渐变效果或 ImageShader
strokeCap -> 笔触线帽类型:round / butt / square

笔触类型包括三种,默认为 butt 即从初始点到终止点;square 在初试点与终止点绘制一个方块;round 即在初试点与终止点绘制一个圆角;

canvas.drawLine(
    Offset(30.0, 30.0), Offset(Screen.width - 30.0, 30.0), Paint());
canvas.drawLine(
    Offset(30.0, 60.0), Offset(Screen.width - 30.0, 60.0), Paint()..strokeWidth = 8.0..isAntiAlias = true);
canvas.drawLine(
    Offset(30.0, 120.0), Offset(Screen.width - 30.0, 120.0), Paint() ..strokeWidth = 8.0 ..isAntiAlias = true..strokeCap = StrokeCap.round);
canvas.drawLine(
    Offset(30.0, 90.0), Offset(Screen.width - 30.0, 90.0), Paint()..strokeWidth = 8.0..isAntiAlias = true..strokeCap = StrokeCap.square);
strokeJoin -> 线结合处:锐角 / 圆弧 / 直线

在线的交汇点处,可以设置交叠时样式,包括:锐角,圆弧和直角样式,官方效果更直接。

style -> 画笔样式:填充 / 描边

style 包括两种样式,默认 PaintingStyle.fill 为填充,PaintingStyle.stroke 为描边;用圆来绘制效果更明显;

canvas.drawCircle(Offset(100.0, 200.0), 50.0, Paint()..strokeWidth = 8.0);
canvas.drawCircle(Offset(260.0, 200.0), 50.0, Paint()..strokeWidth = 8.0..style = PaintingStyle.stroke);
maskFilter -> 模糊遮照效果

模糊效果包括:nomal 内外模糊;solid 内部填充外边模糊,类似于荧光灯效果;outer 内部透明外边模糊;inner 内部模糊,外边正常;和尚建议大家多尝试效果;

canvas.drawLine(Offset(30.0, 280.0), Offset(Screen.width - 30.0, 280.0),
    Paint()..strokeWidth = 8.0..strokeCap = StrokeCap.round..maskFilter = MaskFilter.blur(BlurStyle.normal, 3.0));
canvas.drawLine(Offset(30.0, 310.0), Offset(Screen.width - 30.0, 310.0),
    Paint()..strokeWidth = 8.0..strokeCap = StrokeCap.round..maskFilter = MaskFilter.blur(BlurStyle.outer, 3.0));
canvas.drawLine(Offset(30.0, 340.0), Offset(Screen.width - 30.0, 340.0),
    Paint()..strokeWidth = 8.0..strokeCap = StrokeCap.round..maskFilter = MaskFilter.blur(BlurStyle.solid, 3.0));
canvas.drawLine(Offset(30.0, 370.0), Offset(Screen.width - 30.0, 370.0),
    Paint()..strokeWidth = 8.0..strokeCap = StrokeCap.round..maskFilter = MaskFilter.blur(BlurStyle.inner, 3.0));
blendMode -> 颜色混合模式,类型很多
colorFilter -> 颜色渲染模式,一般是矩阵效果来改变

颜色混合与颜色渲染是两个很神奇的属性,可以通过众多模式调整颜色叠加效果,并与背景色衔接,和尚还无法准确的说明其中叠加的原理;

canvas.drawLine(Offset(30.0, 400.0), Offset(Screen.width - 30.0, 400.0),
    Paint()..strokeWidth = 8.0..blendMode = BlendMode.exclusion..colorFilter = ColorFilter.mode(Colors.white, BlendMode.exclusion));
canvas.drawLine(Offset(30.0, 430.0), Offset(Screen.width - 30.0, 430.0),
    Paint()..strokeWidth = 8.0..blendMode = BlendMode.exclusion..colorFilter = ColorFilter.mode(Colors.yellow, BlendMode.exclusion));
canvas.drawLine(Offset(30.0, 460.0), Offset(Screen.width - 30.0, 460.0),
    Paint()..strokeWidth = 8.0..blendMode = BlendMode.exclusion..colorFilter = ColorFilter.mode(Colors.red, BlendMode.exclusion));
canvas.drawLine(Offset(30.0, 490.0), Offset(Screen.width - 30.0, 490.0),
    Paint()..strokeWidth = 8.0..blendMode = BlendMode.exclusion..colorFilter = ColorFilter.mode(Colors.green, BlendMode.exclusion));

和尚对自定义 View 的了解还并不深入,有很多需要继续学习研究的东西,如有问题,请多多指教!

本文分享自微信公众号 - 阿策小和尚(gh_8297e718c166)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-02-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏跨平台全栈俱乐部

彻底理清前端单页面应用(SPA)的实现原理

21020
来自专栏服务化进程

plupload附件上传插件IE8问题

前段时间遇到一个plupload上传插件问题,在其他浏览器上面运行很正常,但是就是在IE8上面第一次点击上传按钮无反应,后面再连续点击才ok。 我的初始化代码...

10030
来自专栏月小水长

Matplotlib 实战:写一个任意函数极值可视化脚手架

Matplotlib 是 Python 从 Matlab 迁移过来的一个 2D 绘图库,它可以在各种平台上以各种硬拷贝格式和交互式环境生成出具有出版品质的图形,...

13020
来自专栏跨平台全栈俱乐部

如何优化你的超大型React应用

新,会自上而下逐渐刷新整个子孙组件,这样性能损耗重复渲染就会多出很多,所以我们不仅要单一数据来源控制组件刷新,偶尔还需要在shouldComponentUpda...

26240
来自专栏点云PCL

单视图三维重建

《Learning Shape Priors for Single-View 3D Completion and Reconstruction 》。再此分享给大...

23430
来自专栏机器之心

三星3D版「AI上色」算法:神经网络实时渲染真实视频

作者:Kara-Ali Aliev、Dmitry Ulyanov、Victor Lempitsky

9020
来自专栏极乐技术社区

浅谈微信小程序底层架构

其实,小程序开发过程中我们面对的是iOS和Android微信客户端和辅助开发的小程序开发者工具。根据官方文档,这三大运行环境也是有所区别的:

24520
来自专栏大话swift

golang使用实践分享之gin模版引擎使用

最近在看gin,在模版引擎这块被卡克啦----伟大的强啊。今天就来分享一下gin的模版引擎渲染。

20510
来自专栏女程序员的日常_Lin

Vue SSR

vue.js是构建客户端应用程序的框架,在默认情况下,在浏览器输出Vue组件,进行生成DOM和操作DOM。Vue SSR 就是实现将组件渲染为服务器端的HTML...

78810
来自专栏进击的多媒体开发

跨平台渲染引擎之路:拨云见日

最近在工作中越来越多地接触到一些3D以及相比常见特性更酷炫的效果,因此萌发了想要自己从0开始打造一个渲染引擎的念头,一方面是为了更好地实现公司业务的需求,另一方...

13630

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励