Почему переменные класса Flutter CustomPainter не сохраняются

Во Flutter настраивается ли Custom Painter и все его переменные класса с нуля каждый раз, когда вызывается метод рисования? -- когда setState вызывается у родителя?? Я этого не ожидал, но, похоже, так оно и есть:

Я спрашиваю, потому что у меня есть Custom Painter, который содержит объект внутри метода рисования (последовательность точек), который является основой всех последующих эффектов рисования. Но... этот объект в первую очередь требует математики только для того, чтобы быть созданным... и ему требуются размеры холста как часть этого создания... вот почему он находится внутри метода рисования.

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

Я подумал, что лучше всего «по возможности вывести расчеты из метода рисования».

НО... неожиданный результат заключается в том, что когда я проверяю, Flutter всегда говорит, что мой объект равен нулю (в любом случае он каждый раз воссоздается).

Пользовательский художник:

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

class StackPainter02 extends CustomPainter {
  final List<double> brightnessValues;

  Paint backgroundPaint = Paint();
  Paint segmentPaint = Paint();

  List<Offset>? myShape;

  StackPainter02({
    required this.brightnessValues,
  }) {

    backgroundPaint.color = Colors.black;
    backgroundPaint.style = PaintingStyle.fill;
    segmentPaint.style = PaintingStyle.stroke;
  }

  @override
  void paint(Canvas canvas, Size size) {
    final W = size.width;
    final H = size.height;

    segmentPaint.strokeWidth = W / 100;

    canvas.drawPaint(backgroundPaint);

    // unfortunately, we must initialize this here because we need the view dimensions
    if (myShape == null) {
      myShape = _myShapePoints(brightnessValues.length, 0.8, W, H, Offset(W/2,H/2));
    }

    for (int i = 0; i<myShape!.length; i++) {

      // bug fix... problem: using "i+1" results in index out-of-range on wrap-around
      int modifiedIndexPlusOne = i;
      if (modifiedIndexPlusOne == myShape!.length-1) {
        modifiedIndexPlusOne = 0;
      } else {
        modifiedIndexPlusOne++;
      }
      // draw from point i to point i+1
      Offset segmentStart = myShape![i];
      Offset segmentEnd = myShape![modifiedIndexPlusOne];

      double b = brightnessValues[i];
      if (b < 0) {
        b = 0; // !!!- temp debug... problem: brightness array algorithm is not perfect
      }
      int segmentAlpha = (255*b).toInt();
      segmentPaint.color = Color.fromARGB(segmentAlpha, 255, 255, 200);

      canvas.drawLine(segmentStart, segmentEnd, segmentPaint);

    }
  }

  @override
  bool shouldRepaint(covariant StackPainter02 oldDelegate) {
    //return (oldDelegate.brightnessValues[32] != brightnessValues[32]); // nevermind
    return true;
  }
  
}

Метод сборки в родительском:

      @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: CustomPaint(
          painter: //MyCustomPainter(val1: val1, val2: val2),
              StackPainter02(
            brightnessValues: brightnessValues,
          ),
          size: Size.infinite,
        ),
      ),
    );
  }

PS - тикер используется в родительском элементе, а «brightnessValues» пересчитываются при каждом тике тикера -> setState

0 ответов

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