scrollable_positioned_list
是 Flutter 中一个强大的列表控件,它允许通过位置来控制列表滚动。它常用于需要精确控制列表滚动位置的应用场景
依赖
scrollable_positioned_list: ^0.3.8 #精确控制列表滚动位置
代码
提前知道每个模块高度
class MyList extends StatefulWidget { @override _MyListState createState() => _MyListState(); } class _MyListState extends State<MyList> { // 控制列表滚动的控制器 final ItemScrollController _itemScrollController = ItemScrollController(); // 每个列表项的高度列表,生成了 100 个项,高度范围从 50 到 500 final List<double> _itemHeights = List.generate(100, (index) => (index % 10 + 1) * 50.0); // 存储每个列表项的累计高度 final List<double> _cumulativeHeights = []; @override void initState() { super.initState(); _calculateCumulativeHeights(); } // 计算每个列表项的累计高度 void _calculateCumulativeHeights() { double totalHeight = 0.0; // 用于累计高度的变量 _cumulativeHeights.clear(); // 清空之前计算的高度 for (var height in _itemHeights) { totalHeight += height; // 更新累计高度 _cumulativeHeights.add(totalHeight); // 添加到累计高度列表 } } // 滚动到指定的索引 void _scrollToIndex(int index) { // 索引必须在合法范围内 if (index < 0 || index >= _cumulativeHeights.length) return; // 使用 ItemScrollController 滚动到指定索引 _itemScrollController.scrollTo( index: index, // 要滚动到的项的索引 duration: Duration(seconds: 1), // 滚动动画的持续时间 curve: Curves.easeInOut, // 滚动动画的曲线 ); // _itemScrollController.jumpTo(index: index); //直接跳转 } @override Widget build(BuildContext context) { return Column( children: [ ElevatedButton( onPressed: () => _scrollToIndex(10), child: Text('Scroll to Item 10'), ), Expanded( child: ScrollablePositionedList.builder( itemCount: 100, itemScrollController: _itemScrollController, itemBuilder: (context, index) { return Container( height: _itemHeights[index],// 每项的高度来自 _itemHeights 列表 color: index.isEven ? Colors.blue : Colors.green, child: Center( child: Text('Item $index', style: TextStyle(color: Colors.white)), ), ); }, ), ), ], ); } }
文字宽度不确定
class _MyListState extends State<MyList> { // 控制列表滚动的控制器 final ItemScrollController _itemScrollController = ItemScrollController(); // 每个列表项的文本 final List<String> _items = List.generate(100, (index) => 'Item $index' + '数' * index); // 存储每个列表项的宽度 final List<double> _itemWidths = []; @override void initState() { super.initState(); // 初始化时计算每个项的宽度 _calculateItemWidths(); } // 计算每个列表项的宽度 void _calculateItemWidths() { // 清空之前计算的宽度 _itemWidths.clear(); // 创建一个 TextPainter 实例来计算文本的宽度 final textPainter = TextPainter( textDirection: TextDirection.ltr, // 设置文本的方向为从左到右 ); // 遍历每个 item 以计算其宽度 for (var item in _items) { // 设置 TextSpan,定义要计算的文本及其样式 textPainter.text = TextSpan( text: item, // 需要测量的文本内容 style: TextStyle(fontSize: 30), // 设置文本的样式,这里是字体大小为 30 ); // 布局计算文本的实际宽度 textPainter.layout(); // 计算文本宽度,并加上额外的 20 像素的边距 // 这个边距通常用于保证文本不紧贴容器的边缘 _itemWidths.add(textPainter.width + 20); } } // 滚动到指定的索引 void _scrollToIndex(int index) { // 索引必须在合法范围内 if (index < 0 || index >= _itemWidths.length) return; // 使用 ItemScrollController 滚动到指定索引 _itemScrollController.scrollTo( index: index, // 要滚动到的项的索引 duration: Duration(seconds: 1), // 滚动动画的持续时间 curve: Curves.easeInOut, // 滚动动画的曲线 ); } @override Widget build(BuildContext context) { return Column( children: [ // 按钮点击后滚动到列表中的第 10 项 ElevatedButton( onPressed: () => _scrollToIndex(10), // 按钮点击事件,滚动到第 10 项 child: Text('Scroll to Item 10'), // 按钮文本 ), Expanded( child: ScrollablePositionedList.builder( scrollDirection: Axis.horizontal, // 设置为横向滚动 itemCount: _items.length, // 列表项的总数 itemScrollController: _itemScrollController, // 绑定滚动控制器 itemBuilder: (context, index) { // 创建每个列表项 return Container( width: _itemWidths[index], // 每项的宽度来自 _itemWidths 列表 margin: EdgeInsets.symmetric(horizontal: 8), // 每项之间的水平间距 color: index.isEven ? Colors.blue : Colors.green, // 根据索引的奇偶性设置背景颜色 child: Center( child: Text( _items[index], style: TextStyle(color: Colors.white), // 列表项的文本内容和样式 ), ), ); }, ), ), ], ); } }
标签:scrollable,滚动,index,positioned,list,列表,child,文本,itemScrollController From: https://www.cnblogs.com/xbinbin/p/18352615