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

Flutter实现:滚动时同步ListView顶部可见项数据至其他Widget

实现ListView顶部可见项同步展示到容器的解决方案

要实现这个需求,你需要借助ScrollController监听ListView的滚动状态,获取当前顶部可见项的索引,再同步更新上方容器的内容。具体实现如下:

步骤说明

  • 初始化ScrollController和状态变量,用来存储当前顶部可见项的数据
  • 在initState中添加滚动监听,通过ScrollController获取可见区域的item信息,计算出顶部可见的第一个item索引
  • 将上方容器的文本替换为状态变量中的数据
  • 在dispose方法中销毁控制器,避免内存泄漏

完整代码示例

import 'package:flutter/material.dart';

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

  @override
  State<DemoScreen> createState() => _DemoScreenState();
}

class _DemoScreenState extends State<DemoScreen> {
  // 假设你的数据源结构
  final List<Map<String, String>> mylist = List.generate(
    50,
    (index) => {
      'name': 'Item $index',
      'aboutme': 'About item $index - This is some sample description'
    },
  );

  late ScrollController _scrollController;
  Map<String, String>? _topVisibleItem;

  @override
  void initState() {
    super.initState();
    _scrollController = ScrollController();
    // 添加滚动监听
    _scrollController.addListener(_updateTopVisibleItem);
    // 初始化时设置第一个item为默认值
    _topVisibleItem = mylist.first;
  }

  void _updateTopVisibleItem() {
    // 获取当前可见的item位置信息
    final visibleItems = _scrollController.position.getVisibleItems();
    if (visibleItems.isNotEmpty) {
      // 取第一个可见item的索引
      final topIndex = visibleItems.first.index;
      setState(() {
        _topVisibleItem = mylist[topIndex];
      });
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            Container(
              height: 200,
              color: Colors.red,
              child: Center(
                child: _topVisibleItem != null
                    ? Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text(_topVisibleItem!['name']!, style: const TextStyle(fontSize: 20)),
                          const SizedBox(height: 10),
                          Text(_topVisibleItem!['aboutme']!, style: const TextStyle(fontSize: 16)),
                        ],
                      )
                    : const Text('No data', style: TextStyle(fontSize: 20)),
              ),
            ),
            const SizedBox(height: 10),
            Expanded(
              child: Container(
                color: Colors.blue,
                child: ListView.builder(
                  controller: _scrollController, // 绑定控制器
                  itemCount: mylist.length,
                  itemBuilder: (context, index) {
                    return Card(
                      child: ListTile(
                        title: Text(mylist[index]['name']!),
                        subtitle: Text(
                          mylist[index]['aboutme']!,
                          overflow: TextOverflow.ellipsis,
                        ),
                      ),
                    );
                  },
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

关键说明

  • ScrollController的getVisibleItems()方法可以获取当前可见区域内的所有item的位置信息,从中取第一个item的索引即可定位顶部可见项
  • 通过setState更新状态变量,触发UI重建,让上方容器同步显示最新的顶部可见项数据
  • 初始化时要设置默认的顶部项数据,避免初始状态为空

内容的提问来源于stack exchange,提问作者Irfan Ganatra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:25:17