You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 00:05:08