0

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

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,),
    );
  }
}

更新:

这是我目前的代码。

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的代码

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;
  }
}

这就是树的样子:

4

1 回答 1

0

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

您还可以使用 Positioned 小部件而不是 Alignment + Padding 小部件!

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

于 2021-04-30T10:38:33.547 回答