重新建構嵌套清單
這一節使用 Slivers 而不是 ListViews 重建相同的 UI。
前奏在這裡
https://blog.51cto.com/jianguo/4653002
使用 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
更改為
List
。
// Before
List innerLists = [];
變成:
// After
List innerLists = [];
第 3 步
現在是時候重建内部清單了。的
SliverList
類是比原始略有不同
ListView
的類,與主要差異是的外觀
delegate
。原始版本
ListView
對所有内容都使用對象,不知道内部建構器構造函數将被
shrinkWrap
.
// Before
@override
void initState() {
super.initState();
for (int i = 0; i < numberOfLists; 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(),
),
);
}
}
// After
@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(
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 {
@override
Widget 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 {
List innerLists = [];
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(
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) => _innerList[index],
childCount: numberOfItemsPerList,
),
),
);
}
}
@override
Widget build(BuildContext context) {
return CustomScrollView(slivers: innerLists);
}
}
@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('這裡是堅果前端小課堂!',
style: TextStyle(color: Colors.white)),
),
],
),
),
],
),
);
}
}
Color randomColor() =>
Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);