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 MyList extends StatefulWidget {
  const MyList({super.key});

  @override
  State<MyList> createState() => _MyListState();
}

class _MyListState extends State<MyList> {
  // 控制列表滚动的控制器
  final ItemScrollController _itemScrollController = ItemScrollController();

  // 每个列表项的文本
  final List<String> _items =
      List.generate(100, (index) => 'Item $index' + '数' * index);

  @override
  void initState() {
    super.initState();
  }

  // 滚动到指定的索引
  void _scrollToIndex(int index) {
    // 索引必须在合法范围内
    if (index < 0 || index >= _items.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(
                margin: EdgeInsets.symmetric(horizontal: 8), // 每项之间的水平间距
                color:
                    index.isEven ? Colors.blue : Colors.green, // 根据索引的奇偶性设置背景颜色
                child: Center(
                  child: Text(
                    _items[index],
                    style: TextStyle(color: Colors.white), // 列表项的文本内容和样式
                  ),
                ),
              );
            },
          ),
        ),
      ],
    );
  }
}

 

posted on 2024-08-10 18:30  鲤斌  阅读(178)  评论(0编辑  收藏  举报