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
相关产品推荐
相关产品推荐

