我是多余的 發表於 2022-12-12 11:38:55

Flutter CustomPaint绘制widget使用示例

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>CustomPaint 介绍</li><li>使用 CustomPaint</li><ul class="second_class_ul"><li>size 的大小。</li><li>isComplex</li><li>willChange</li><li>foregroundPainter</li></ul><li>动画</li><ul class="second_class_ul"></ul></ul></div><p class="maodian"></p><h2>CustomPaint 介绍</h2>
<p>Flutter CustomPaint 提供了一个 canvas,可以在绘制阶段在上面进行绘制内容。</p>
<div class="cros igoods"><div class="goodsin" data-img="https://img14.360buyimg.com/pop/jfs/t1/170002/16/30387/81056/632c294fEa3a5a254/7735b0c226b0f5ff.jpg" data-name="深度探索Flutter——企业应用开发实战(计算机技术开发与应用丛书)" data-owner="京东自营" data-price="95" data-tgid="38" data-url="https://union-click.jd.com/jdc?e=&amp;p=JF8BAMkJK1olXwUHUlpaCkwWC18IGVkdXQMDUG4ZVxNJXF9RXh5UHw0cSgYYXBcIWDoXSQVJQwYAVlZdDUoTHDZNRwYlOXYFCCEpayt0SBF8fRBAFUZWUiwkeEcbM2gNHF4dXwMBZF5eDkwXAmoIK2sVXDZQOobrvpOysnPcsdTA1ZEyVW5dD00WCm8PH1gRXQUBZF5VDHtUVypcWBhdbTYyV25tOEsnAF9WdVpGWwQDBwlaZhZEWWcJWhsUMwAFVF5ZDEkVM20JGlkXbTY"></div></div>
<p>需要绘制时,CustomPaint 首先要求它的 painter 在当前画布上绘画,然后它绘画它的 child,在绘画完它的 child 之后,要求他的 foregroundPainter 绘画。</p>
<p>需要在从原点开始并包含给定大小的区域的矩形内作画。 (如果在这些边界之外绘画,则分配的内存可能不足以光栅化绘画命令,并且结果行为未定义。)要保证在这些边界内绘画,请考虑使用 ClipRect。</p>
<p class="maodian"></p><h2>使用 CustomPaint</h2>
<div class="jb51code"><pre class="brush:cpp;">const CustomPaint({
    super.key,
    this.painter,
    this.foregroundPainter,
    this.size = Size.zero,
    this.isComplex = false,
    this.willChange = false,
    super.child,
})
</pre></div>
<p>最重要就是这个 painter,painter 需要自定义。</p>
<div class="jb51code"><pre class="brush:cpp;">class MyPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.0;
    canvas.drawLine(
      Offset(0, 10),
      Offset(
          100,
          10,
      ),
      paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
}
}
</pre></div>
<p>需要重写两个方法,在 paint 方法中进行绘制。如果绘制不受外界影响,shouldRepaint 返回 false 就好。</p>
<div class="jb51code"><pre class="brush:cpp;">CustomPaint(painter: MyPainter(),);
</pre></div>
<p>把 MyPainter 赋值给参数 painter 就好了。</p>
<p class="maodian"></p><h3>size 的大小。</h3>
<p>如果 CustomPaint 的约束可以为 0 的话,那么 size 的值 <code>Size(0,0)</code>,就是说,size 的值总是 Constrains 的最小 width,最小 height。有两种办法可以改变 size。</p>
<ul><li>可以给 CustomPaint 加上约束,比如加一个 SizedBox</li></ul>
<div class="jb51code"><pre class="brush:css;"> SizedBox(
      height: 20,
      width: 20,
      child: CustomPaint(
          painter: MyPainter(),
      ))
</pre></div>
<ul><li>可以直接指定 size 参数。</li></ul>
<div class="jb51code"><pre class="brush:css;"> SizedBox(
      height: 20,
      width: 20,
      child: CustomPaint(
          size:Size(30,30),
          painter: MyPainter(),
      ))
</pre></div>
<p>size 参数可以在 constrains 的范围内起到作用。在本例中,约束为 20, size 为 30,最后传给 paint 方法的 size 为 20。 tight 约束下 size 参数无效,只有 在loose 约束下 ,size 参数才能起到作用。</p>
<p class="maodian"></p><h3>isComplex</h3>
<p>是否提示应该缓存该层的绘画。如果 为false,则合成器将自己来决定这一层是否应该缓存。</p>
<p class="maodian"></p><h3>willChange</h3>
<p>是否应该告知缓存层这幅画在下一帧中可能会发生变化。如果 isComplex 为 true,才需要考虑这个参数。</p>
<p class="maodian"></p><h3>foregroundPainter</h3>
<p>默认绘制的层是在 child 之下,foregroundPainter 在 child 之上。</p>
<p class="maodian"></p><h2>动画</h2>
<p>CustomPainter 有一个 可选的参数 <code>Listenable? repaint</code> ,是用来做动画的。</p>
<p>举个例子。</p>
<div class="jb51code"><pre class="brush:cpp;">class MyPainter extends CustomPainter {
MyPainter(Animation&lt;double&gt; animation) :_animation=animation, super(repaint: animation);
final Animation&lt;double&gt; _animation;
@override
void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.0;
    canvas.drawLine(
      Offset(0, 10),
      Offset(
          100*_animation.value,
          10,
      ),
      paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
@override
State&lt;MyStatefulWidget&gt; createState() =&gt; _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State&lt;MyStatefulWidget&gt; with SingleTickerProviderStateMixin{
late AnimationController controller=
      AnimationController(duration: Duration(seconds: 2),vsync: this)..repeat();
@override
Widget build(BuildContext context) {
    return SizedBox(
      height: 20,
      width: 20,
      child: CustomPaint(
          painter: MyPainter(controller.view),
      ));
}
}
</pre></div>
<p>会看到一条红色的直线由短变长。</p>
<p>以上就是Flutter CustomPaint绘制widget使用示例的详细内容,更多关于Flutter CustomPaint绘制widget的资料请关注琼殿技术社区其它相关文章!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>Flutter交互并使用小工具管理其状态widget的state详解</li><li>Flutter框架解决盒约束widget和assets里加载资产技术</li><li>Flutter Widget开发之Focus组件图文详解</li><li>Flutter&nbsp;Widget开发Shortcuts快捷键实例</li><li>Flutter Widget之NavigationBar使用详解</li><li>Flutter Widget之FutureBuilder使用示例详解</li><li>Flutter Widget 之package mason实现详解</li><li>Flutter&nbsp;Widget移动UI框架使用Material和密匙Key实战</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: Flutter CustomPaint绘制widget使用示例