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

如何在CustomScrollView的SliverList中实现滚动到指定索引功能?

问题修复方案

核心错误原因

  • CustomScrollView绑定的是独立的普通ScrollController,和你初始化的用于滚动定位的AutoScrollController完全没有关联,滚动指令无法作用到实际视图
  • 视口边界计算没有扣除顶部固定的SliverAppBar高度,会导致滚动定位偏移错误
  • SliverChildBuilderDelegate未指定childCount,会出现列表条目越界问题

修复后完整代码

import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
 
void main() => runApp(MyApp());
 
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Scroll To Index Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Scroll To Index Demo'),
    );
  }
}
 
class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
 
  final String title;
 
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
 
class _MyHomePageState extends State<MyHomePage> {
  static const maxCount = 100;
  final random = math.Random();
  final scrollDirection = Axis.vertical;
 
  late AutoScrollController controller;
  late List<List<int>> randomList;
 
  @override
  void initState() {
    super.initState();
    controller = AutoScrollController(
        // 修正视口边界,扣除顶部固定的SliverAppBar高度
        viewportBoundaryGetter: () =>
            Rect.fromLTRB(0, kToolbarHeight, 0, MediaQuery.of(context).padding.bottom),
        axis: scrollDirection);
    randomList = List.generate(
        maxCount, (index) => <int>[index, (200 * random.nextDouble()).toInt()]);
  }
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        // 替换为AutoScrollController实例
        controller: controller,
        slivers: [
          SliverAppBar(
            pinned: true,
            title: Text("App bar"),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) {
                return Padding(
                  padding: EdgeInsets.all(8),
                  child: _getRow(
                    randomList[index][0],
                    math.max(randomList[index][1].toDouble(), 50.0),
                  ),
                );
              },
              // 补充列表总条目数
              childCount: maxCount
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _scrollToIndex,
        tooltip: 'Increment',
        child: Text(counter.toString()),
      ),
    );
  }
 
  int counter = -1;
  Future _scrollToIndex() async {
    setState(() {
      counter++;
 
      if (counter >= maxCount) counter = 0;
    });
 
    await controller.scrollToIndex(counter,
        preferPosition: AutoScrollPosition.begin);
    controller.highlight(counter);
  }
 
  Widget _getRow(int index, double height) {
    return _wrapScrollTag(
      index: index,
      child: Container(
        padding: EdgeInsets.all(8),
        alignment: Alignment.topCenter,
        height: height,
        decoration: BoxDecoration(
            border: Border.all(color: Colors.lightBlue, width: 4),
            borderRadius: BorderRadius.circular(12)),
        child: Text('index: $index, height: $height'),
      ),
    );
  }
 
  Widget _wrapScrollTag({required int index, required Widget child}) =>
      AutoScrollTag(
        key: ValueKey(index),
        controller: controller,
        index: index,
        child: child,
        highlightColor: Colors.black.withOpacity(0.7),
      );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:15:02