為了避免 Pixel Overflow,實務上會在 body 使用 SingleChildScrollView
,但這會導致 ListView
無法顯示。
Version
Flutter 3.24.5
Flutter
- Android 與 iOS 都成功使用
ShrinkView
使ListView
自行決定高度
GridView
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
const Home({super.key});
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
final List<String> _data = List.generate(
3,
(index) => 'Item ${index + 1}',
);
Widget build(BuildContext context) {
var appBar = AppBar(
title: const Text(
'ListView.builder with shrinkWrap',
),
);
var listView = ListView.builder(
itemCount: _data.length,
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
_data[index],
),
),
);
},
child: Container(
color: Colors.transparent,
padding: EdgeInsets.zero,
child: Text(
_data[index],
),
),
);
},
);
var body = SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: listView,
),
);
return Scaffold(
appBar: appBar,
body: body,
);
}
}
Line 51
var body = SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: listView,
),
);
SingleChildScrollView
:外部沒有
限制高度,當內部高度大於
裝置高度時,會自動產生垂直卷軸
Line 24
var listView = ListView.builder(
itemCount: _data.length,
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
_data[index],
),
),
);
},
child: Container(
color: Colors.transparent,
padding: EdgeInsets.zero,
child: Text(
_data[index],
),
),
);
},
);
shrinkWrap: true
:由ListView
本身內容決定高度physics: const NeverScrollableScrollPhysics()
:ListView
不顯示卷軸
Conclusion
ListView
預設會有卷軸,因此會搭配無限高度,但因為 body 已經使用SingleChildScrollView
對高度不受限,所以預設ListView
搭配SingleChildScrollView
會無法顯示,必須搭配shrinkWrap: true
由ListView
本身內容產生高度
才能顯示ListView
本身亦有卷軸,但由於在 body 已經使用SingleChildScrollView
有卷軸,為了避免兩層卷軸,shrinkWrap: true
通常會一起搭配physics: const NeverScrollableScrollPhysics()
使用