Flutter 使用SingleChildScrollView滚动时,CustomPainter会产生抖动效果

Flutter 使用SingleChildScrollView滚动时,CustomPainter会产生抖动效果,flutter,dart,Flutter,Dart,嗨,我正在玩CustomPainter,并试图用水平卷轴在随机位置和半径放置气泡。使用SingleChildScrollView会导致抖动效果错误。你知道如何避免这种情况吗 导入“包装:颤振/材料.省道”; 将“dart:ui”导入为ui; 导入“包:flifter/services.dart”; 类Bubble扩展了StatefulWidget{ 最后清单项目; 气泡({Key-Key,this.items=const[]}):超级(Key:Key); @凌驾 _BubbleState cr

嗨,我正在玩CustomPainter,并试图用水平卷轴在随机位置和半径放置气泡。使用SingleChildScrollView会导致抖动效果错误。你知道如何避免这种情况吗

导入“包装:颤振/材料.省道”;
将“dart:ui”导入为ui;
导入“包:flifter/services.dart”;
类Bubble扩展了StatefulWidget{
最后清单项目;
气泡({Key-Key,this.items=const[]}):超级(Key:Key);
@凌驾
_BubbleState createState();
}
类_BubbleState扩展状态{
双宽、双高;
@凌驾
小部件构建(构建上下文){
height=MediaQuery.of(context).size.height;
宽度=MediaQuery.of(context).size.width/2;
debugPrint(“获得$width,$height”);
返回SingleChildScrollView(
物理:物理(),
滚动方向:轴水平,
孩子:定制油漆(
大小:大小((100*widget.items.length*1.3).toDouble(),高度),
画家:
电路油漆工(高度:高度,宽度:宽度,项目:小部件。项目),
),
);
}
}
类CirclePaint扩展了CustomPainter{
最终双倍高度、宽度;
最后清单项目;
最终用户界面。图像;
CirclePaint({this.height,this.width,this.items,this.image});
@凌驾
空心油漆(帆布,尺寸){
var paint=paint()
…color=Colors.pinkAccent
..冲程宽度=5
…style=PaintingStyle.fill
..strokeCap=strokeCap.round;
双星tx=120;
双星=150*1.5;
双原点起点=150*1.5;
双原点起点x=120;
双中线偏移=70;
双均匀圆偏移=20;
双oddCircleYOffset=20;
双星型=75;
列表可能的最小半径=[85,90];
列表可能梯度=[100110];
items.asMap().forEach((索引,值){
画布.画圈(偏移量(startX,startY),startRadius,绘画);
int nextHumanIndex=指数+2;
int currentHumanIndex=索引+1;
如果(((nextHumanIndex)%3==0)){
startX=startX+(startRadius*2)+20;
星形=原始起点+中线偏移;
startRadius=(可能的最小半径)
…托利斯特()
..shuffle())
.首先;
}否则{
startY=startY+(startRadius*2)+20;
startRadius=(可能的最小半径)
…托利斯特()
..shuffle())
.首先;
如果(currentHumanIndex%3==0){
startRadius=(可能的最小半径)
…托利斯特()
..shuffle())
.首先;
startX=startX+(startRadius*2)+20;
startY=原始startY;
}
}
如果(nextHumanIndex.isEven){
startY=startY+evenCircleYOffset;
}
});
}
@凌驾
bool应重新绘制(自定义代理){
//TODO:实现应重新绘制
返回false;
}
}
这和卷轴物理有关吗

import 'package:flutter/material.dart';
import 'dart:ui' as ui;

import 'package:flutter/services.dart';

class Bubble extends StatefulWidget {
  final List<String> items;
  Bubble({Key key, this.items = const []}) : super(key: key);

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

class _BubbleState extends State<Bubble> {
  double width, height;
  @override
  Widget build(BuildContext context) {
    height = MediaQuery.of(context).size.height;
    width = MediaQuery.of(context).size.width / 2;
    debugPrint("got with $width, $height");
    return SingleChildScrollView(
      physics: ScrollPhysics(),
      scrollDirection: Axis.horizontal,
      child: CustomPaint(
        size: Size((100 * widget.items.length * 1.3).toDouble(), height),
        painter:
            CirclePainter(height: height, width: width, items: widget.items),
      ),
    );
  }
}

class CirclePainter extends CustomPainter {
  final double height, width;
  final List<String> items;
  final ui.Image image;
  CirclePainter({this.height, this.width, this.items, this.image});
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.pinkAccent
      ..strokeWidth = 5
      ..style = PaintingStyle.fill
      ..strokeCap = StrokeCap.round;

    double startX = 120;
    double startY = 150 * 1.5;
    double originalStartY = 150 * 1.5;
    double originalStartX = 120;
    double midCircleYOffset = 70;
    double evenCircleYOffset = 20;
    double oddCircleYOffset = 20;
    double startRadius = 75;
    List<double> possibleSmallRadius = [85, 90];
    List<double> possibleBigRadius = [100, 110];

    items.asMap().forEach((index, value) {
      canvas.drawCircle(Offset(startX, startY), startRadius, paint);
      int nextHumanIndex = index + 2;
      int currentHumanIndex = index + 1;
      if (((nextHumanIndex) % 3 == 0)) {
        startX = startX + (startRadius * 2) + 20;
        startY = originalStartY + midCircleYOffset;
        startRadius = (possibleSmallRadius
              ..toList()
              ..shuffle())
            .first;
      } else {
        startY = startY + (startRadius * 2) + 20;
        startRadius = (possibleSmallRadius
              ..toList()
              ..shuffle())
            .first;
        if (currentHumanIndex % 3 == 0) {
          startRadius = (possibleSmallRadius
                ..toList()
                ..shuffle())
              .first;

          startX = startX + (startRadius * 2) + 20;
          startY = originalStartY;
        }
      }

      if (nextHumanIndex.isEven) {
        startY = startY + evenCircleYOffset;
      }
    });
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return false;
  }
}