Пользовательский класс Painter не отображается в Stack flutter

По какой-то причине Stack виджет не показывает Container с CustomPaint.

Однако если удалить из Stack, работает нормально. Что мне здесь не хватает?

class _DemoNavBar extends State<DemoNavBar> {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        home:
        Stack(
          children: <Widget>[
            Container(child: CustomPaint(painter: CurvePainter()))
      ],
    )
    );
  }
}

class CurvePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint();
    paint.color = Colors.green[800];
    paint.style = PaintingStyle.fill;

    var path = Path();

    path.moveTo(0, size.height - 100); 

    path.lineTo(size.width * 0.5, size.height - 100); 
    path.quadraticBezierTo(size.width * 0.7, size.height, size.width * 0.9,
        size.height - 100); 
    path.lineTo(size.width, size.height - 100); 
    path.lineTo(size.width, size.height); 
    path.lineTo(0, size.height);
    canvas.drawPath(path, paint);
  }

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

Спасибо!

1 ответ

Решение

Проверка источника CustomPaint это говорит

  /// The size that this [CustomPaint] should aim for, given the layout
  /// constraints, if there is no child.
  ///
  /// Defaults to [Size.zero].
  ///
  /// If there's a child, this is ignored, and the size of the child is used
  /// instead.

Итак, дайте ему размер. Другие решения включают 1) предоставление ширины и высоты родителюContainer из CustomPaint и 2) предоставить ребенка для CustomPaint который будет игнорировать size предоставлено в решении ниже.


Я проверил, что этот код работает нормально. size: MediaQuery.of(context).size использует полный размер экрана.

void main() {
  runApp(SO());
}

class SO extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DemoNavBar(),
    );
  }
}

class DemoNavBar extends StatefulWidget {
  @override
  _DemoNavBar createState() => _DemoNavBar();
}

class _DemoNavBar extends State<DemoNavBar> {
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        CustomPaint(
          size: MediaQuery.of(context).size,
          painter: CurvePainter(),
        )
      ],
    );
  }
}

class CurvePainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint();
    paint.color = Colors.green[800];
    paint.style = PaintingStyle.fill;

    var path = Path();

    path.moveTo(0, size.height - 100);

    path.lineTo(size.width * 0.5, size.height - 100);
    path.quadraticBezierTo(size.width * 0.7, size.height, size.width * 0.9, size.height - 100);
    path.lineTo(size.width, size.height - 100);
    path.lineTo(size.width, size.height);
    path.lineTo(0, size.height);
    canvas.drawPath(path, paint);
  }

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

Теперь причина в том, что Container не имеет родителя или дочернего элемента, чтобы обеспечить размер, необходимый для полного размера экрана, и отлично работает без Stack. Когда используется стек, размер стека становится равным нулю, который передается индивидуальному художнику.

Эквивалентный код можно записать как

Stack(
  children: <Widget>[
    Container(
      width: MediaQuery.of(context).size.width,
      height: MediaQuery.of(context).size.height,
      child: CustomPaint(
        painter: CurvePainter(),
      ),
    )
  ],
);

конечный результат

Другие вопросы по тегам