写点什么

flutter 中的列表的性能优化前奏

作者:坚果前端
  • 2021 年 11 月 21 日
  • 本文字数:2368 字

    阅读完需:约 8 分钟

这里是坚果前端小课堂,大家喜欢的话,可以关注我的公众号“坚果前端,”,或者加我好友,获取更多精彩内容

嵌套列表 - ShrinkWrap 与 Slivers

使用 ShrinkWrap 的列表列表

下面是一些使用ListView对象呈现列表列表的代码,内部列表的shrinkWrap值设置为 true。shrinkWrap强行评估整个内部列表,允许它请求有限的高度,而不是通常的ListView对象高度,即无穷大!


下面是基本的代码结构:


ListView(  // Setting `shrinkWrap` to `true` here is both unnecessary and expensive.  children: <Widget>[    ListView.builder(      itemCount: list1Children.length,      itemBuilder: (BuildContext context, int index) {        return list1Children[index];      },      // This forces the `ListView` to build all of its children up front,      // negating much of the benefit of using `ListView.builder`.      shrinkWrap: true,    ),    ListView.builder(      itemCount: list2Children.length,      itemBuilder: (BuildContext context, int index) {        return list2Children[index];      },      // This forces the `ListView` to build all of its children up front,      // negating much of the benefit of using `ListView.builder`.      shrinkWrap: true,    ),    ...  ],)
复制代码


注意:观察外部ListView没有将其shrinkWrap 值设置为true。只有内部列表需要设置shrinkWrap


另请注意:虽然ListView.builder(默认情况下)有效地构建其子项,为您节省构建屏幕外小部件的不必要成本,但设置 shrinkWraptrue覆盖此默认行为!


import 'package:flutter/material.dart';import 'dart:math' as math;void main() {  runApp(ShrinkWrApp());}class ShrinkWrApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    return MaterialApp(      debugShowCheckedModeBanner: false,      title: 'ShrinkWrap vs Slivers',      home: Scaffold(        appBar: AppBar(          title: const Text("ShrinkWrap, Street Rat, I don't, Buy that!"),        ),        body: const ShrinkWrapSlivers(),      ),    );  }}class ShrinkWrapSlivers extends StatefulWidget {  const ShrinkWrapSlivers({    Key? key,  }) : super(key: key);  @override  _ShrinkWrapSliversState createState() => _ShrinkWrapSliversState();}class _ShrinkWrapSliversState extends State<ShrinkWrapSlivers> {  List<ListView> innerLists = [];  final numLists = 15;  final numberOfItemsPerList = 100;  @override  void initState() {    super.initState();    for (int i = 0; i < numLists; i++) {      final _innerList = <ColorRow>[];      for (int j = 0; j < numberOfItemsPerList; j++) {        _innerList.add(const ColorRow());      }      innerLists.add(        ListView.builder(          itemCount: numberOfItemsPerList,          itemBuilder: (BuildContext context, int index) => _innerList[index],          shrinkWrap: true,          physics: const NeverScrollableScrollPhysics(),        ),      );    }  }  @override  Widget build(BuildContext context) {    return ListView.builder(        itemCount: numLists,        itemBuilder: (context, index) => innerLists[index]);  }}@immutableclass ColorRow extends StatefulWidget {  const ColorRow({Key? key}) : super(key: key);  @override  State createState() => ColorRowState();}class ColorRowState extends State<ColorRow> {  Color? color;  @override  void initState() {    super.initState();    color = randomColor();  }  @override  Widget build(BuildContext context) {    print('Building ColorRowState');    return Container(      decoration: BoxDecoration(        gradient: LinearGradient(          begin: Alignment.topLeft,          end: Alignment.bottomRight,          colors: [            randomColor(),            randomColor(),          ],        ),      ),      child: Row(        children: <Widget>[          Padding(            padding: const EdgeInsets.all(8.0),            child: Container(height: 50, width: 50, color: Colors.white),          ),          Flexible(            child: Column(              children: const <Widget>[                Padding(                  padding: EdgeInsets.all(8),                  child: Text('这里是 坚果前端小课堂!',                      style: TextStyle(color: Colors.white)),                ),              ],            ),          ),        ],      ),    );  }}Color randomColor() =>    Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);
复制代码

一切都建立起来!

当您滚动浏览此 UI 并注意该ColorBarState.build方法的调用方式时,会出现可怕的部分 。每个内部列表包含 100 个元素,因此当 UI 加载时,您会立即看到 100 个“Building ColorBarState”的实例打印到控制台,


更糟糕的是,一旦向下滚动大约一百行,就会再生成一百行。😱😱😱



而且你滑动的快的时候列表会抖动!

重新构建嵌套列表

要了解如何使您的用户免受卡顿威胁,请等待我的第二节,下一节将使用 Slivers 而不是 ListViews 重建相同的 UI。

发布于: 4 小时前阅读数: 4
用户头像

坚果前端

关注

此间若无火炬,我便是唯一的光 2020.10.25 加入

公众号:“坚果前端”,51CTO博客首席体验官,专注于大前端技术的分享,包括Flutter,小程序,安卓,VUE,JavaScript。

评论

发布
暂无评论
flutter中的列表的性能优化前奏