Flutter 性能不佳清单

rel*_*ope 6 performance listview flutter

我尝试使用 Listview 和 Sliverlist,但列表的性能非常慢。\n即使项目是从互联网加载的,滚动也非常慢。

\n

有人对缓慢的代码有什么想法吗?

\n
import 'dart:typed_data';\nimport 'dart:math';\n\nimport 'package:flutter/material.dart';\nimport 'package:flutter/rendering.dart';\nimport 'package:flutter/widgets.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:font_awesome_flutter/font_awesome_flutter.dart';\nimport 'package:impex_shop/bloc/warenkorb_bloc.dart';\nimport 'package:impex_shop/data/articlepodo.dart';\nimport 'package:impex_shop/routenames.dart';\nimport 'package:impex_shop/services/repository.dart';\nimport 'package:impex_shop/styles/impex_icons.dart';\nimport 'package:impex_shop/styles/impex_styles.dart';\nimport 'package:impex_shop/utils/utils.dart';\nimport 'package:impex_shop/widgets/myfuturebuilder.dart';\n\nclass SearchResultsWidget extends StatefulWidget {\n  final Map<String, String> search;\n\n  SearchResultsWidget(this.search);\n\n  @override\n  _SearchResultsWidgetState createState() =>\n      _SearchResultsWidgetState(this.search);\n}\n\nclass _SearchResultsWidgetState extends State<SearchResultsWidget> {\n  Map<String, String> search;\n  Future<ArticleIdList> _articleIds;\n\n  _SearchResultsWidgetState(this.search);\n\n  @override\n  void initState() {\n    super.initState();\n    _articleIds = Repository().queryArticleSearch(search);\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return FutureBuilder(\n      future: _articleIds,\n      //showProgressIndicator: true,\n      builder: (context, snapshot) {\n        if (snapshot.connectionState == ConnectionState.done &&\n            snapshot.hasData) {\n          ArticleIdList articleIds = snapshot.data;\n          if (articleIds.articleIds.length == 0) {\n            return Container(\n              padding: EdgeInsets.symmetric(\n                  horizontal: ImpexStyle.horizontalPadding),\n              child: Text('Kein Artikel gefunden'),\n            );\n          }\n          return CustomScrollView(\n            slivers: <Widget>[\n              SliverList(\n                delegate: SliverChildBuilderDelegate(\n                  (BuildContext context, int index) {\n                    if (index == 0) {\n                      return Container(\n                        height: ImpexStyle.verticalPadding,\n                      );\n                    }\n                    Future<Article> article = Repository()\n                        .queryArticleDetails(articleIds.articleIds[index - 1]);\n                    return MyFutureBuilder(\n                      future: article,\n                      builder: (context, article) {\n                        return SearchResultLineWidget(article: article);\n                      },\n                    );\n                  },\n                  childCount: articleIds.articleIds.length + 1,\n                ),\n              )\n            ],\n          );\n        } else if (snapshot.hasError) {\n          return Row(\n            children: <Widget>[\n              Icon(\n                Icons.error,\n                color: ImpexColors.errorColor,\n                size: 30,\n              ),\n              Expanded(\n                child: Text(\n                  '${snapshot.error}',\n                  style: TextStyle(color: ImpexColors.errorColor),\n                ),\n              )\n            ],\n          );\n        } else {\n          return Center(\n            child: CircularProgressIndicator(),\n          );\n        }\n      },\n    );\n  }\n}\n\nclass SearchResultLineWidget extends StatefulWidget {\n  const SearchResultLineWidget({this.article});\n\n  final Article article;\n\n  @override\n  State<StatefulWidget> createState() {\n    return SearchResultLineState(article);\n  }\n}\n\nclass SearchResultLineState extends State<SearchResultLineWidget> {\n  SearchResultLineState(this._article);\n\n  final Article _article;\n  Future<String> _articleImageData;\n\n  @override\n  void initState() {\n    super.initState();\n    _articleImageData = Repository().queryArticleImage(\n      _article.id,\n      width: ImpexStyle.imageSize,\n      height: ImpexStyle.imageSize,\n    );\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    WarenkorbBloc warenkorbBloc = BlocProvider.of<WarenkorbBloc>(context);\n    bool isInWarenkorb = (warenkorbBloc.currentState as WarenkorbLoaded)\n            .warenkorbLines[_article.id] !=\n        null;\n\n    return Column(\n      children: <Widget>[\n        FlatButton(\n          onPressed: (() {\n            Navigator.pushNamed(context, RouteName.ARTICLE_DETAIL,\n                arguments: _article.id);\n          }),\n          child: Row(\n            children: <Widget>[\n              FutureBuilder<String>(\n                future: _articleImageData,\n                builder: (context, snapshot) {\n                  if (snapshot.hasData &&\n                      snapshot.connectionState == ConnectionState.done) {\n                    var imageData = snapshot.data;\n                    if (imageData.isEmpty || imageData == 'null')\n                      return Container(\n                        width: ImpexStyle.imageSize.toDouble(),\n                        height: ImpexStyle.imageSize.toDouble(),\n                        child: EmptyImageIcon(),\n                      );\n                    return Container(\n                      height: ImpexStyle.imageSize.toDouble(),\n                      width: ImpexStyle.imageSize.toDouble(),\n                      child: Stack(children: <Widget>[\n                        Image(\n                          image: MemoryImage(\n                            Uint8List.fromList(imageData.codeUnits),\n                          ),\n                        ),\n                        isInWarenkorb\n                            ? Icon(FontAwesomeIcons.shoppingCart)\n                            : Center(),\n                      ]),\n                    );\n                  } else if (snapshot.hasError) {\n                    return Container(\n                      width: ImpexStyle.imageSize.toDouble(),\n                      height: ImpexStyle.imageSize.toDouble(),\n                      child: Text(snapshot.error),\n                    );\n                  }\n\n                  return Container(\n                    width: ImpexStyle.imageSize.toDouble(),\n                    height: max(96, ImpexStyle.imageSize.toDouble()),\n                    child: Center(),\n                  );\n                },\n              ),\n              Container(width: ImpexStyle.horizontalPadding),\n              Flexible(\n                child: Column(\n                  crossAxisAlignment: CrossAxisAlignment.start,\n                  children: <Widget>[\n                    Row(\n                      children: <Widget>[\n                        Expanded(\n                          child: Text(\n                            _article.no,\n                            style: ImpexStyle.fontStyleSmall,\n                          ),\n                        ),\n                        Spacer(),\n                        PriceLagerWidget(_article),\n                      ],\n                    ),\n                    Text(_article.name, style: ImpexStyle.fontStyleNormal)\n                  ],\n                ),\n              )\n            ],\n          ),\n        ),\n        Divider(color: ImpexColors.dividerColor),\n      ],\n    );\n  }\n}\n\nclass PriceLagerWidget extends StatelessWidget {\n  PriceLagerWidget(this._article)\n      : _articlePrice = Repository().queryArticlePrice(_article.id);\n\n  final Article _article;\n  final Future<ArticlePrice> _articlePrice;\n\n  @override\n  Widget build(BuildContext context) {\n    return MyFutureBuilder<ArticlePrice>(\n      future: _articlePrice,\n      builder: (context, articlePrice) {\n        String priceString = getPriceString(articlePrice, context);\n        return Row(\n          children: <Widget>[\n            Row(\n              children: <Widget>[\n                _article.isRaffleWin\n                    ? RaffleWinIcon()\n                    : Text('\xe2\x82\xac', style: ImpexStyle.fontStyleSmall),\n                Text(' $priceString ', style: ImpexStyle.fontStyleSmall)\n              ],\n            ),\n            AvailabilityIcon(this._article.availabilityColor)\n          ],\n        );\n      },\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Gui*_*oux 4

我认为使用ListView.builder可能会对您有所帮助,因为它只会渲染可见的项目。

这是一篇关于小部件优化的文章,解释了构建某些小部件时的性能差异。