Flutter CustomPaint没有重绘

4
我无法让自定义画笔进行重新绘制。我尝试使用Listenable、回调函数、setState等方法,但屏幕上没有任何重绘。

文档中提到:

触发重绘的最有效方式是:

  • 通过扩展CustomPainter类并在其构造函数中提供repaint参数,在需要重绘时通知其侦听器对象。
  • 通过扩展Listenable(例如通过ChangeNotifier)和实现CustomPainter,使对象直接提供通知。 在任一情况下,CustomPaint widget或RenderCustomPaint渲染对象将侦听Listenable,并在动画滴答时重绘,避免了管道的构建和布局阶段。

但代码并未按预期工作。

这是我使用的代码:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

main() {
  runApp(MaterialApp(
    home: Scaffold(appBar: AppBar(), body: Pad()),
  ));
}

class Pad extends StatefulWidget {
  @override
  _PadState createState() => _PadState();
}

class _PadState extends State<Pad> {
  @override
  Widget build(BuildContext context) {
    final painter = Painter();
    return GestureDetector(
        onTap: () {
          setState(() {
            painter.addY(10);
          });
        },
        child: CustomPaint(
          painter: painter,
          child: Container(),
        ));
  }
}

class Painter extends CustomPainter {
  double y = 10;

  addY(val) {
    y += val;
  }

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawCircle(Offset(size.width / 2, y++), 100, Paint());
  }

  @override
  bool shouldRepaint(Painter oldDelegate) {
    return true;
  }
}
3个回答

6

我使用ChangeNotifier来调用有状态小部件的setState方法? - Guilherme

1

我不知道为什么,但当我添加一个空的 DropdownButtonFormField 小部件时,它可以工作。

即使 shouldRepaint 函数总是返回 false。当点击 GestureDetector 时,paint 函数总是重新调用。

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

main() {
  runApp(MaterialApp(
    home: Scaffold(appBar: AppBar(), body: const Pad()),
  ));
}

class Pad extends StatefulWidget {
  const Pad({Key? key}) : super(key: key);

  @override
  _PadState createState() => _PadState();
}

class _PadState extends State<Pad> {
  @override
  Widget build(BuildContext context) {
    final painter = Painter();
    return Stack(
      children: [
        SizedBox(
          width: 0,
          height: 0,
          child: DropdownButtonFormField<String>(
              onChanged: (value) {}, items: const []),
        ),
        GestureDetector(
            onTap: () {
              setState(() {
                painter.addY(10);
              });
            },
            child: CustomPaint(
              painter: Painter(),
              child: Container(),
            )),
      ],
    );
  }
}

class Painter extends CustomPainter {
  double y = 10;

  addY(val) {
    y += val;
  }

  @override
  void paint(Canvas canvas, Size size) {
    debugPrint('paint');
    canvas.drawCircle(Offset(size.width / 2, y++), 100, Paint());
  }

  @override
  bool shouldRepaint(Painter oldDelegate) {
    return false;
  }
}

0
对于“Đức Hải Trần”代码,只需删除 SizedBox() 并将 shouldRepaint 返回值更改为 'true',然后它就可以正常工作了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接