showModalBottomSheet Проблема с производительностью появляется примерно через 3 секунды - PullRequest
0 голосов
/ 27 мая 2020

У меня есть несколько modalBottomSheet в моем приложении, чтобы показать, большинство из них имеют простое дерево виджетов, за исключением одного, в котором есть 10 виджетов DropDownBottom

Каждый из них загружает около 200 элементов, каждый элемент является виджетом состоят из двух основных виджетов: текста и изображения

, когда я нажимаю

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

Открытие занимает около 3 секунд, загружает modalBottomSheet, и он просто появляется в эмуляторе без анимации скольжения вверх , другие modalBottomSheets в приложении загружаются отлично, вот пример кода, который я использую.

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

Я новичок в разработке в целом, поэтому я ценю, есть ли какие-либо ресурсы о том, как измерить и улучшить производительность в приложениях флаттера.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 27 мая 2020

Вам следует избегать одновременного рендеринга 2000 виджетов.

Прежде всего посмотрите на ListView виджет, а это builder(). Попробуйте провести рефакторинг своего кода и поместить все элементы в этот ListView. Это значительно увеличит вашу производительность по той причине, что ListView.builder() позволяет вам не хранить все ваши виджеты в памяти все время.

https://api.flutter.dev/flutter/widgets/ListView/ListView.builder.html

0 голосов
/ 27 мая 2020

Кажется, ваш bottomModalSheet слишком тяжелый. Он загружается только после того, как дети завершат сборку. Измените размер изображений, которые вы используете внутри bottomModalSheet.

Обычно приложение отладки работает очень медленно по сравнению с приложением выпуска. Создайте apk приложения: flutter build apk --split-per-abi. Установите сгенерированный apk build/app/outputs/apk/release/app-armeabi-v7a-release.apk и посмотрите, сохраняется ли проблема.

...