Flutter 含ExpansionTiles的可滚动列表如何实现按钮自适应定位
Flutter 自适应底部按钮布局实现方案
需求逻辑
针对包含多个ExpansionTile的可滚动视图,Test按钮需要满足两种布局规则:
- 所有列表内容(含展开状态的子项)总高度未超出屏幕可视区域时,按钮固定显示在页面底部
- 列表总高度超出屏幕可视范围时,按钮排列在列表内容末尾,随列表整体滚动,需滚动到列表底部才可看到
原有代码问题
当前嵌套SingleChildScrollView+ 设了shrinkWrap: true的ListView的写法,无论内容长度是否溢出屏幕,按钮都会直接跟在列表末尾,无法实现内容较短时贴底的效果,同时嵌套两层滚动组件会产生不必要的性能开销。
最终实现代码
直接使用CustomScrollView搭配SliverList、SliverFillRemaining即可实现效果,不需要额外监听展开状态、手动计算内容高度,组件展开/收起时布局会自动适配:
import 'package:flutter/material.dart'; class MyHomePage extends StatelessWidget { MyHomePage({Key? key}) : super(key: key); final List datas = [1, 2, 3, 4, 5, 6]; @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: CustomScrollView( slivers: [ // ExpansionTile列表区域 SliverList( delegate: SliverChildBuilderDelegate( (context, i) { return ExpansionTile( title: Text(datas[i].toString()), children: List.generate( datas.length, (index) => Text(datas[index].toString()), ), ); }, childCount: datas.length, ), ), // 自适应按钮区域 SliverFillRemaining( // 核心参数:内容不足时自动填充视口剩余空间,内容溢出时按子组件实际高度布局 hasScrollBody: false, child: Align( alignment: Alignment.bottomCenter, child: Padding( padding: const EdgeInsets.all(16.0), child: ElevatedButton( onPressed: () {}, child: const Text('Test'), ), ), ), ) ], ), ), ); } }
效果参考
- 内容未溢出时按钮贴底效果:

- 内容溢出时按钮随列表滚动效果:

内容的提问来源于stack exchange,提问作者Alex Apps
相关产品推荐
相关产品推荐

