這里是堅(jiān)果前端小課堂,大家喜歡的話,可以關(guān)注我的公眾號“堅(jiān)果前端,”,或者加我好友,獲取更多精彩內(nèi)容
嵌套列表 - ShrinkWrap 與 Slivers使用 ShrinkWrap 的列表列表
下面是一些使用??ListView?
?對象呈現(xiàn)列表列表的代碼,內(nèi)部列表的??shrinkWrap?
?值設(shè)置為 true。??shrinkWrap?
?強(qiáng)行評估整個(gè)內(nèi)部列表,允許它請求有限的高度,而不是通常的??ListView?
?對象高度,即無窮大!
下面是基本的代碼結(jié)構(gòu):
ListView(
// Setting `shrinkWrap` to `true` here is both unnecessary and expensive.
children:[
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?
? 值設(shè)置為??true?
?。只有內(nèi)部列表需要設(shè)置??shrinkWrap?
?。另請注意:雖然?
?ListView.builder?
?(默認(rèn)情況下)有效地構(gòu)建其子項(xiàng),為您節(jié)省構(gòu)建屏幕外小部件的不必要成本,但設(shè)置 ??shrinkWrap?
?為??true?
?覆蓋此默認(rèn)行為!
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 dont, Buy that!"),
),
body: const ShrinkWrapSlivers(),
),
);
}
}
class ShrinkWrapSlivers extends StatefulWidget {
const ShrinkWrapSlivers({
Key? key,
}) : super(key: key);
@override
_ShrinkWrapSliversState createState() => _ShrinkWrapSliversState();
}
class _ShrinkWrapSliversState extends State{
ListinnerLists = [];
final numLists = 15;
final numberOfItemsPerList = 100;
@override
void initState() {
super.initState();
for (int i = 0; i < numLists; i++) {
final _innerList =[];
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]);
}
}
@immutable
class ColorRow extends StatefulWidget {
const ColorRow({Key? key}) : super(key: key);
@override
State createState() => ColorRowState();
}
class ColorRowState extends State{
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:[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(height: 50, width: 50, color: Colors.white),
),
Flexible(
child: Column(
children: const[
Padding(
padding: EdgeInsets.all(8),
child: Text(這里是 堅(jiān)果前端小課堂!,
style: TextStyle(color: Colors.white)),
),
],
),
),
],
),
);
}
}
Color randomColor() =>
Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);
一切都建立起來!
當(dāng)您滾動瀏覽此 UI 并注意該??ColorBarState.build?
?方法的調(diào)用方式時(shí),會出現(xiàn)可怕的部分 。每個(gè)內(nèi)部列表包含 100 個(gè)元素,因此當(dāng) UI 加載時(shí),您會立即看到 100 個(gè)“Building ColorBarState”的實(shí)例打印到控制臺,
更糟糕的是,一旦向下滾動大約一百行,就會再生成一百行。????????????
而且你滑動的快的時(shí)候列表會抖動!
重新構(gòu)建嵌套列表
要了解如何使您的用戶免受卡頓威脅,請等待我的第二節(jié),下一節(jié)將使用 Slivers 而不是 ListViews 重建相同的 UI。