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

Flutter中ListView.builder行列同步滚动及滚动像素获取问题

解决方案

1. 实现列同步滚动(用List管理控制器)

用List<ScrollController>批量管理所有纵向ListView的控制器,通过监听核心控制器的滚动事件,同步更新所有列的滚动位置,避免逐个创建控制器的冗余代码。

核心步骤:

  • 将原有代码改为StatefulWidget,用于管理控制器的生命周期
  • 初始化与列数匹配的控制器列表
  • 监听第一个控制器的滚动事件,同步所有其他控制器的偏移量
  • 组件销毁时释放所有控制器,防止内存泄漏

2. 获取滚动像素值

直接通过ScrollController的offset或position.pixels属性即可获取当前滚动的像素值,可在滚动监听回调中实时获取,或在任意业务逻辑中调用。


修改后的完整代码

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: const SyncScrollTable(),
      ),
    );
  }
}

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

  @override
  State<SyncScrollTable> createState() => _SyncScrollTableState();
}

class _SyncScrollTableState extends State<SyncScrollTable> {
  late final List<List<String>> users;
  late final List<ScrollController> verticalControllers;
  double _currentVerticalOffset = 0;

  @override
  void initState() {
    super.initState();
    // 初始化1000×1000测试数据
    users = List.generate(1000, (j) => List.generate(1000, (i) => '$j\n$i'));
    // 创建对应数量的滚动控制器
    verticalControllers = List.generate(users.length, (_) => ScrollController());

    // 监听第一个控制器,同步所有列滚动
    verticalControllers.first.addListener(() {
      final offset = verticalControllers.first.offset;
      if (offset != _currentVerticalOffset) {
        _currentVerticalOffset = offset;
        // 同步所有控制器偏移量
        for (final controller in verticalControllers) {
          if (controller.offset != offset) {
            controller.jumpTo(offset);
          }
        }
        // 实时打印滚动像素值
        debugPrint('当前纵向滚动像素:$_currentVerticalOffset');
      }
    });
  }

  @override
  void dispose() {
    // 销毁所有控制器,释放内存
    for (final controller in verticalControllers) {
      controller.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        ListView.builder(
          padding: const EdgeInsets.all(0),
          scrollDirection: Axis.horizontal,
          itemCount: users.length,
          itemBuilder: (BuildContext context, int index) {
            return Container(
              width: 40,
              child: ListView.builder(
                controller: verticalControllers[index],
                scrollDirection: Axis.vertical,
                addAutomaticKeepAlives: false,
                shrinkWrap: true,
                primary: false,
                itemCount: users.length,
                itemBuilder: (BuildContext context, int indexF) {
                  return Container(
                    width: 40,
                    height: 40,
                    margin: const EdgeInsets.only(right: 1.0, bottom: 1.0),
                    color: Colors.blueAccent,
                    child: Center(
                      child: Text(
                        users[index][indexF],
                        textAlign: TextAlign.center,
                        style: const TextStyle(fontSize: 12),
                      ),
                    ),
                  );
                },
              ),
            );
          },
        ),
        // 示例:在页面右上角显示当前滚动像素值
        Positioned(
          top: 20,
          right: 20,
          child: Container(
            padding: const EdgeInsets.all(8),
            color: Colors.white.withOpacity(0.8),
            child: Text('纵向滚动像素:${_currentVerticalOffset.toStringAsFixed(1)}'),
          ),
        ),
      ],
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 03:13:14