showModalBottomSheet性能问题需要3秒左右才能出现

问题描述 投票:0回答:1

我的应用程序中有几个modalBottomSheet要显示,其中大部分都有简单的部件树,只有一个有10个DropDownBottom部件的除外

每一个都加载了大约200个项目,每个项目都是一个小部件,由两个主要的小部件组成一个文本和一个图像。

当我按

onPressed: () {
        showModalBottomSheet(context: context, builder: picksWidget, isScrollControlled: true);
      }

打开加载modalBottomSheet需要3秒左右的时间,而且它只是出现在模拟器中,没有向上滑动的动画,应用中的其他modalBottomSheet加载完全正常,这里是我使用的代码的例子。

import 'package:flutter/material.dart';
import 'package:myapp/data/picked.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:myapp/data/picks.dart';
import 'package:myapp/data/Icons.dart';

Widget buildPickerBottomSheet(BuildContext context) {
  return Wrap(children: <Widget>[
    PickerList(),
  ]);
}

class PickerList extends StatelessWidget {
  const PickerList({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        Container(
          padding: EdgeInsets.all(20),
          child: Row(
            children: <Widget>[
              AutoSizeText(
                'Pick ',
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                textAlign: TextAlign.right,
                maxLines: 1,
              ),
            ],
          ),
        ),
        SizedBox(
          height: 5,
        ),
        PickerRow(
          typeOne: 'vr',
          typeTwo: 'er',
          type: 'r',
        ),
        PickerRow(
          typeOne: 'vq',
          typeTwo: 'eq',
          type: 'q',
        ),
        PickerRow(
          typeOne: 'vw',
          typeTwo: 'ew',
          type: 'w',
        ),
        PickerRow(
          typeOne: 'vz',
          typeTwo: 'ez',
          type: 'z',
        ),
        PickerRow(
          typeOne: 'vy',
          typeTwo: 'ey',
          type: 'y',
        ),
        SizedBox(
          height: 10,
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            RaisedButton(
              child: Text('Add'),
              onPressed: () async {
                print('added');
              },
            ),
            RaisedButton(
              child: Text('Cancel'),
              onPressed: () {
                Navigator.pop(context);
              },
            )
          ],
        ),
        SizedBox(
          height: 50,
        )
      ],
    );
  }
}

class PickerRow extends StatelessWidget {
  final String typeOne;
  final String typeTwo;
  final String type;
  PickerRow({@required this.typeOne, @required this.typeTwo, @required this.type});
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(left: 20, right: 20),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          DropDownMenu(
            pickType: typeOne,
          ),
          Container(
            width: 2,
            height: 30,
            color: Colors.blue,
          ),
          Container(
            height: 30,
            width: 30,
            child: Image(
              image: AssetImage(AppIcons.types[type]),
            ),
          ),
          Container(
            width: 2,
            height: 30,
            color: Colors.red,
          ),
          DropDownMenu(
            pickType: typeTwo,
          ),
        ],
      ),
    );
  }
}

class DropDownMenu extends StatefulWidget {
  //which position will this pick for
  final String pickType;
  DropDownMenu({@required this.pickType});
  @override
  _DropDownMenuState createState() => _DropDownMenuState();
}

class _DropDownMenuState extends State<DropDownMenu> {
  //get a list of the picks to display in the drop down
  static List<DropdownMenuItem> getDropDownItems() {
    List<DropdownMenuItem<String>> dropDownItems = [];
    for (int i = 0; i < Picks.picksNames.length; i++) {
      String pick = Picks.picksNames[i];
      var newItem = DropdownMenuItem(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            CircleAvatar(
              backgroundImage: AssetImage(AppIcons.picks[pick]),
              radius: 15,
            ),
            SizedBox(
              width: 4,
            ),
            AutoSizeText(
              pick,
              maxLines: 1,
            ),
          ],
        ),
        value: pick,
      );
      dropDownItems.add(newItem);
    }
    return dropDownItems;
  }

  var items = getDropDownItems();

  @override
  Widget build(BuildContext context) {
    String chosenItem = Picked.selection[widget.pickType];
    return DropdownButton<String>(
      value: chosenItem,
      items: items,
      onChanged: (value) {
        setState(() {
          chosenItem = value;
        });
        Picked.selection[widget.pickType] = value; 
      },
    );
  }
}

我是一般的开发新手,所以如果有关于如何衡量和提高flutter应用的性能的资源,我很感激。

谢谢。

android-studio flutter dart flutter-layout flutter-animation
1个回答
0
投票

看来你的 bottomModalSheet 太重了。只有在孩子们完成构建后才会加载。bottomModalSheet.

通常情况下,调试应用比发布应用要慢很多.生成应用的apk: flutter build apk --split-per-abi. 安装生成的apk build/app/outputs/apk/release/app-armeabi-v7a-release.apk 看看问题是否仍然存在。


0
投票

你应该避免一次渲染2000个小部件。

首先看看 ListView 小部件和它的 builder(). 试着重构你的代码,并把你所有的项目放在这个。ListView. 它将增加你的性能很多,由于原因 ListView.builder() 允许你不要一直在内存中存储所有的widgets。

https:/api.flutter.devflutterwidgetsListViewListView.builder.html。

© www.soinside.com 2019 - 2024. All rights reserved.