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

如何在Flutter中实现滚动时逐步显示隐藏元素的列表布局?

Flutter实现带遮挡滚动动画的列表布局

需要实现一个包含7个元素的列表:初始状态下第6、7个元素被第5个元素遮挡在下方;当列表向上滚动时,第5个元素逐渐向上移开,逐步露出第6、7个元素。

实现思路

  • 用ScrollController监听列表滚动偏移量,以此驱动动画逻辑
  • 对第5个列表项应用平移动画,滚动超过临界距离后,跟随滚动向上移动
  • 第6、7个列表项初始定位在第5个项下方,通过滚动偏移控制其平移距离与透明度,实现逐步显示效果
  • 直接在build方法中结合滚动偏移计算控件变换参数,无需额外动画控制器

完整代码示例

import 'package:flutter/material.dart';

class AnimatedOccludedList extends StatefulWidget {
  const AnimatedOccludedList({super.key});

  @override
  State<AnimatedOccludedList> createState() => _AnimatedOccludedListState();
}

class _AnimatedOccludedListState extends State<AnimatedOccludedList> {
  final ScrollController _scrollController = ScrollController();
  double _item5Offset = 0.0;
  // 触发动画的临界滚动距离,可根据列表项高度调整
  final double _triggerScroll = 100.0;

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(_onScroll);
  }

  void _onScroll() {
    final scrollOffset = _scrollController.offset;
    setState(() {
      _item5Offset = scrollOffset > _triggerScroll ? scrollOffset - _triggerScroll : 0.0;
    });
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final itemHeight = 80.0;
    return Scaffold(
      appBar: AppBar(title: const Text("遮挡滚动动画列表")),
      body: ListView.builder(
        controller: _scrollController,
        padding: const EdgeInsets.symmetric(vertical: 20),
        itemCount: 7,
        itemBuilder: (context, index) {
          final itemIndex = index + 1;

          if (itemIndex == 5) {
            return Transform.translate(
              offset: Offset(0, -_item5Offset),
              child: _buildListItem(itemIndex, itemHeight),
            );
          } else if (itemIndex >= 6) {
            final initialOffset = itemHeight;
            final visibleOffset = _item5Offset > initialOffset ? _item5Offset - initialOffset : 0.0;
            return Transform.translate(
              offset: Offset(0, initialOffset - visibleOffset),
              child: Opacity(
                opacity: visibleOffset / initialOffset,
                child: _buildListItem(itemIndex, itemHeight),
              ),
            );
          } else {
            return _buildListItem(itemIndex, itemHeight);
          }
        },
      ),
    );
  }

  Widget _buildListItem(int index, double height) {
    return Container(
      height: height,
      margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      decoration: BoxDecoration(
        color: Colors.blue.shade100,
        borderRadius: BorderRadius.circular(8),
        border: Border.all(color: Colors.blue.shade300),
      ),
      alignment: Alignment.center,
      child: Text(
        "列表项 $index",
        style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
      ),
    );
  }
}

void main() => runApp(const MaterialApp(home: AnimatedOccludedList()));

代码说明

  • 第5个列表项通过Transform.translate实现向上平移,滚动超过_triggerScroll后开始跟随滚动
  • 第6、7个列表项初始被第5个项完全遮挡,随着第5个项上移,通过平移抵消初始遮挡距离,同时配合透明度动画实现平滑显示
  • _buildListItem方法统一构建列表项样式,可根据需求自定义布局、颜色等属性

内容的提问来源于stack exchange,提问作者felipe Souza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:35:01