日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于flutter列表的性能优化,你必须要了解的

發布時間:2025/3/19 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于flutter列表的性能优化,你必须要了解的 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這里是堅果前端小課堂,大家喜歡的話,可以關注我的公眾號“堅果前端,”,或者加我好友,獲取更多精彩內容

嵌套列表 - 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(默認情況下)有效地構建其子項,為您節省構建屏幕外小部件的不必要成本,但設置 shrinkWrap為true覆蓋此默認行為!

import 'package:flutter/material.dart'; import 'dart:math' as math;void main() {runApp(ShrinkWrApp()); }class ShrinkWrApp extends StatelessWidget {@overrideWidget 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;@overridevoid 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(),),);}}@overrideWidget build(BuildContext context) {return ListView.builder(itemCount: numLists,itemBuilder: (context, index) => innerLists[index]);} }@immutable class ColorRow extends StatefulWidget {const ColorRow({Key? key}) : super(key: key);@overrideState createState() => ColorRowState(); }class ColorRowState extends State<ColorRow> {Color? color;@overridevoid initState() {super.initState();color = randomColor();}@overrideWidget 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。

使用 Slivers 的列表列表

下面的代碼構建了與之前相同的 UI,但這次它使用Slivers 而不是收縮包裝ListView對象。本頁的其余部分將引導您逐步完成更改。

如何將嵌套列表遷移到 Slivers

第1步

首先,將最外面的 ListView 更改為SliverList.

// Before @override Widget build(BuildContext context) {return ListView.builder(itemCount: numberOfLists,itemBuilder: (context, index) => innerLists[index],); }

變成:

// After @override Widget build(BuildContext context) {return CustomScrollView(slivers: innerLists); }

第2步

其次,將內部列表的類型從List<ListView>更改為 List<SliverList>。

// Before List<ListView> innerLists = [];

變成:

// After List<SliverList> innerLists = [];

第 3 步

現在是時候重建內部列表了。的SliverList類是比原始略有不同ListView的類,與主要差異是的外觀delegate。

原始版本ListView對所有內容都使用對象,不知道內部構建器構造函數將被shrinkWrap.

// Before @override void initState() {super.initState();for (int i = 0; i < numberOfLists; 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(),),);} }

更改后,ListView對象被替換為SliverList對象,每個對象都使用一個SliverChildBuilderDelegate來提供高效的按需構建。

// After @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(SliverList(delegate: SliverChildBuilderDelegate((BuildContext context, int index) => _innerList[index],childCount: numberOfItemsPerList,),),);} }

完整代碼:

import 'package:flutter/material.dart'; import 'dart:math' as math;void main() {runApp(SliversApp()); }class SliversApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false,title: 'ShrinkWrap vs Slivers',home: Scaffold(appBar: AppBar(title: const Text("Revenge of the Slivers"),),body: const ShrinkWrapSlivers(),),);} }class ShrinkWrapSlivers extends StatefulWidget {const ShrinkWrapSlivers({Key? key,}) : super(key: key);@override_ShrinkWrapSliversState createState() => _ShrinkWrapSliversState(); }class _ShrinkWrapSliversState extends State<ShrinkWrapSlivers> {List<SliverList> innerLists = [];final numLists = 15;final numberOfItemsPerList = 100;@overridevoid 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(SliverList(delegate: SliverChildBuilderDelegate((BuildContext context, int index) => _innerList[index],childCount: numberOfItemsPerList,),),);}}@overrideWidget build(BuildContext context) {return CustomScrollView(slivers: innerLists);} }@immutable class ColorRow extends StatefulWidget {const ColorRow({Key? key}) : super(key: key);@overrideState createState() => ColorRowState(); }class ColorRowState extends State<ColorRow> {Color? color;@overridevoid initState() {super.initState();color = randomColor();}@overrideWidget 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);

Lazy building!

上面的代碼已經應用了這些更改。運行應用程序并注意 Flutter 不再需要立即渲染 100 個 ColorRow 小部件。當您滾動時,會動態構建更多小部件,正如您所期望的那樣。更好的是,一直滾動到下一個列表也不會產生任何特殊費用。

Flutter 會根據需要重新構建小部件,而且很快。

這節課對你來說怎么樣,可以的話,支持一下吧

你快速的滑動的時候會發現,這個時候的列表沒有抖動!

總結

以上是生活随笔為你收集整理的关于flutter列表的性能优化,你必须要了解的的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。