Как использовать два нестандартных художника во флаттере

Я сделал 2 нестандартных художника

1.

class DrawTriangle1 extends CustomPainter {
  DrawTriangle1() {
    painter = Paint()
      ..shader =
          LinearGradient(colors: [Colors.red, Colors.white]).createShader(rect)
      ..style = PaintingStyle.fill;
  }

  @override
  void paint(Canvas canvas, Size size) {
    var path = Path();

    path.moveTo(0, 0);
    path.lineTo(size.width, 0);
    path.lineTo(size.width, size.height / 2);
    path.close();
    canvas.drawPath(path, painter);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
  1. class DrawTriangle2 extends CustomPainter {
      DrawTriangle2() {
        painter = Paint()
          ..shader = LinearGradient(colors: [
            Color(0xfffff),
            Color(0xff076585),
          ]).createShader(rect)
          ..style = PaintingStyle.fill;
      }
    
      @override
      void paint(Canvas canvas, Size size) {
        var path = Path();
        path.lineTo(size.width / 2, size.height / 4);
        path.lineTo(0, size.height / 2);
        path.close();
    
        canvas.drawPath(path, painter);
      }
    
      @override
      bool shouldRepaint(CustomPainter oldDelegate) {
        return true;
      }
    }
    

Если я использую нестандартный рисовальщик для создания одной формы, он рисует ее с начала страницы.

ListView(
          children: <Widget>[
            CustomPaint(
              painter: DrawTriangle1(),
              size: Size(MediaQuery.of(context).size.width,
          MediaQuery.of(context).size.height), ,
            )
          ],
        )

но если я добавлю еще один в список, как это, второй треугольник начинается в нижней части первого экрана.

ListView(
          children: <Widget>[
            CustomPaint(
              painter: DrawTriangle1(),
              size: Size(MediaQuery.of(context).size.width,
                  MediaQuery.of(context).size.height),
            ),
            CustomPaint(
              painter: DrawTriangle2(),
              size: Size(MediaQuery.of(context).size.width,
                  MediaQuery.of(context).size.height),
            )
          ],
        ),

Как сделать так, чтобы у них обоих была одна и та же отправная точка.

2 ответа

Используйте стек.

      @override
  Widget build(BuildContext context) {
    return Stack(children: [
            CustomPaint(
              painter: DrawTriangle1(),
              size: Size(MediaQuery.of(context).size.width,
                  MediaQuery.of(context).size.height),
            ),
            CustomPaint(
              painter: DrawTriangle2(),
              size: Size(MediaQuery.of(context).size.width,
                  MediaQuery.of(context).size.height),
            )
          ]);
  }

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

Поэтому замените виджет ListView на виджет стека, который решит вашу проблему.

Stack( //change 
          children: <Widget>[
            CustomPaint(
              painter: DrawTriangle1(),
              size: Size(MediaQuery.of(context).size.width,
                  MediaQuery.of(context).size.height),
            ),
            CustomPaint(
              painter: DrawTriangle2(),
              size: Size(MediaQuery.of(context).size.width,
                  MediaQuery.of(context).size.height),
            )
          ],
        ),
Другие вопросы по тегам