首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Flutter -包含过多堆栈子对象的性能下降(jank)

Flutter -包含过多堆栈子对象的性能下降(jank)
EN

Stack Overflow用户
提问于 2021-04-30 18:01:16
回答 1查看 84关注 0票数 0

我必须渲染一棵叶子数量未知的树。但是当树叶数量太高时,应用程序的性能会急剧下降。我能做些什么来提高性能?叶子的数量可以达到1000,所以1000个子节点的堆栈会降低性能是很正常的,但是我能做什么呢?提前感谢!

代码语言:javascript
复制
class Tree extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final Random random = new Random();
    final leaf = Provider.of<Leafs>(context, listen: false);
    final heightTree = (MediaQuery.of(context).size.width - 60) * (772 / 480); //Ratio of the tree
    final heightTreeTrunk = heightTree * (169 / 772); //Ratio of the treetrunk
    const leafSize = 20.0;
    final children = <Widget>[
      Padding(
        padding: EdgeInsets.fromLTRB(30, 15, 30, 0),
        child: Image.asset(
          'assets/images/tree2.png',
          color: Colors.grey.shade600,
        ),
      ),
    ];
    for (var i = 0; i < leaf.tot; i++) {
      double angle = random.nextInt(100) / 100 * 2 * pi;
      double ran = sqrt(random.nextInt(100) / 100);
      children.add(
        Padding(
          padding: EdgeInsets.fromLTRB(5, 0, 5, heightTreeTrunk),
          child: Align(
            alignment: Alignment(
              ran * cos(angle),
              ran * sin(angle),
            ),
            child: RotationTransition(
              turns: AlwaysStoppedAnimation(random.nextInt(360) / 360),
              child: SizedBox(
                height: leafSize,
                width: leafSize,
                child: Image.asset(
                  'assets/images/leaf8.png',
                ),
              ),
            ),
          ),
        ),
      );
    }
    return Container(
      height: heightTree,
      child: Stack(children: children,),
    );
  }
}

更新:

这是我目前的代码。

代码语言:javascript
复制
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'dart:math';

import '../painter/leaf.dart';
import '../providers/number_leaf.dart';

class Tree extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final Random random = Random();
    final _numberLeaf = Provider.of<NumberLeaf>(context, listen: false);
    final _heightTree = (MediaQuery.of(context).size.width - 60) *
        (772 / 480); //Ratio of the tree
    final _heightTreeTrunk = _heightTree * (120 / 772); //Ratio of the treetrunk

    final _children = <Widget>[];
    
    for (var i = 0; i < _numberLeaf.tot; i++) {
      final double angle = random.nextDouble() * 2 * pi;
      final double ran = sqrt(random.nextDouble());
      _children.add(
        Align(
          alignment: Alignment(
            ran * cos(angle),
            ran * sin(angle),
          ),
          child: Transform.rotate(
            angle: random.nextDouble() * 2 * pi,
            child: Leaf(),
          ),
        ),
      );
    }
    return Container(
      decoration: BoxDecoration(
      image: DecorationImage(
        image: AssetImage('assets/images/tree2.png'),
        colorFilter: ColorFilter.mode( Colors.grey.shade600, BlendMode.srcIn)
      ),
    ),
      height: _heightTree,
      child: Padding(
        padding: EdgeInsets.fromLTRB(5, 0, 5, _heightTreeTrunk),
        child: Stack(
          children: _children,
        ),
      ),
    );
  }
}

这是leafpainter的代码

代码语言:javascript
复制
import 'package:flutter/material.dart';

class Leaf extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: const Size(40, 60), //size of the leaf
      painter: LeafPainter(),
    );
  }
}

class LeafPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final double width = size.width;
    final double height = size.height;

    final Paint paint_0 = Paint()
      ..color = const Color.fromARGB(200, 19, 150, 25)  //green
      ..style = PaintingStyle.fill
      ..strokeWidth = 14.95;
    final Paint paint_1 = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1;
    final Paint paint_2 = Paint()
      ..color = Colors.brown.shade800
      ..style = PaintingStyle.fill
      ..strokeWidth = 12.23;

    Path path_0 = Path();
    path_0.moveTo(width * 0.1223000, height * 0.3841667);
    path_0.quadraticBezierTo(width * 0.1499250, height * 0.2975000,
        width * 0.2059000, height * 0.2272167);
    path_0.cubicTo(width * 0.2595500, height * 0.1635667, width * 0.2943500,
        height * 0.1454833, width * 0.4089750, height * 0.1237833);
    path_0.cubicTo(width * 0.5149250, height * 0.1089167, width * 0.6031750,
        height * 0.1097167, width * 0.6993250, height * 0.0974333);
    path_0.quadraticBezierTo(width * 0.8040250, height * 0.0849167,
        width * 0.8882000, height * 0.0280833);
    path_0.quadraticBezierTo(width * 0.8890750, height * 0.1651667,
        width * 0.8404250, height * 0.2313500);
    path_0.cubicTo(width * 0.7884500, height * 0.3151167, width * 0.7394000,
        height * 0.3545667, width * 0.6384750, height * 0.3916667);
    path_0.cubicTo(width * 0.5696250, height * 0.4122500, width * 0.4952750,
        height * 0.4190667, width * 0.3900750, height * 0.4185833);
    path_0.quadraticBezierTo(width * 0.2472000, height * 0.4168167,
        width * 0.1223000, height * 0.3841667);
    path_0.close();

    canvas.drawPath(path_0, paint_0);  // the leaf
    canvas.drawPath(path_0, paint_1);  // the border of the leaf

    final BorderRadius borderRadius = BorderRadius.circular(15);
    final Rect rect = Rect.fromLTRB(
        0.03 * width, 0.39 * height, 0.135 * width, 0.37 * height);
    final RRect outer = borderRadius.toRRect(rect);
    canvas.drawRRect(outer, paint_2);  // the stem of the leaf
  }

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

这是树的样子:Tree

EN

回答 1

Stack Overflow用户

发布于 2021-04-30 18:38:34

您可以尝试将RotationTransition替换为Transform.rotate小部件,因为您使用的是AlwaysStoppedAnimation。

您也可以使用定位的小部件,而不是您的对齐+填充小部件!

请注意,最有效的方法是使用一个CustomPainter小部件绘制全部三个小部件!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67331929

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档