如何在Flutter中实现顶部按钮随滚动显隐且ListView嵌套Card的UI?
Flutter实现滚动时顶部按钮隐藏/显示 + Card包裹ListView
实现思路
通过ScrollController监听ListView的滚动方向:向上滚动时隐藏顶部按钮,向下滚动时显示;同时将ListView嵌套在Card组件内,实现卡片式容器效果。
完整代码示例
import 'package:flutter/material.dart'; class ScrollHideButtonPage extends StatefulWidget { const ScrollHideButtonPage({super.key}); @override State<ScrollHideButtonPage> createState() => _ScrollHideButtonPageState(); } class _ScrollHideButtonPageState extends State<ScrollHideButtonPage> { final ScrollController _scrollController = ScrollController(); // 控制按钮显隐的偏移量,0为显示,-kToolbarHeight为隐藏 double _buttonOffset = 0; // 记录上一次的滚动位置 double _lastScrollPosition = 0; @override void initState() { super.initState(); _scrollController.addListener(_handleScroll); } void _handleScroll() { final currentPosition = _scrollController.position.pixels; // 向上滚动时隐藏按钮 if (currentPosition > _lastScrollPosition && _buttonOffset == 0) { setState(() { _buttonOffset = -kToolbarHeight; }); } // 向下滚动时显示按钮 else if (currentPosition < _lastScrollPosition && _buttonOffset != 0) { setState(() { _buttonOffset = 0; }); } _lastScrollPosition = currentPosition; } @override void dispose() { _scrollController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ // 带Card包裹的ListView Padding( padding: const EdgeInsets.all(16.0), child: Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: ListView.builder( controller: _scrollController, padding: const EdgeInsets.only(top: kToolbarHeight + 16), itemCount: 50, itemBuilder: (context, index) { return ListTile( title: Text('列表项 $index'), subtitle: Text('这是第${index+1}个列表内容'), ); }, ), ), ), // 可滚动隐藏的顶部按钮栏 AnimatedPositioned( duration: const Duration(milliseconds: 300), top: _buttonOffset, left: 16, right: 16, child: Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), child: SizedBox( height: kToolbarHeight, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton.icon( onPressed: () {}, icon: const Icon(Icons.add), label: const Text('添加'), ), ElevatedButton.icon( onPressed: () {}, icon: const Icon(Icons.delete), label: const Text('删除'), ), ], ), ), ), ), ], ), ); } }
关键细节说明
- 滚动监听:通过
ScrollController的addListener方法实时获取滚动位置,对比当前与上一次位置判断滚动方向,触发按钮显隐状态切换。 - 动画过渡:使用
AnimatedPositioned实现按钮的平滑位移动画,避免显隐切换过于生硬。 - Card包裹ListView:给Card设置
elevation(阴影)、borderRadius(圆角),并通过Padding控制Card与屏幕边缘的间距,提升UI质感。 - 内存管理:在
dispose方法中销毁ScrollController,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Aakash
相关产品推荐
相关产品推荐

