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

ListWheelScrollViewX无法滚动至起始位置的解决请求

问题解决:ListWheelScrollViewX无法滚动到索引0的问题

你的问题核心在于FixedExtentScrollController的创建时机与更新逻辑错误:当前你在build方法中每次创建新的控制器,initialItem参数仅在控制器初始化时生效;父组件更新initialHeight后,新控制器的initialItem虽设为0,但ListWheelScrollViewX不会自动触发滚动动作。

修复步骤:

  • 将控制器提升为State类的成员变量,在initState中初始化并绑定初始值
  • 通过didUpdateWidget监听initialHeight的变化,当父组件传入的值变为0时,主动调用控制器的滚动方法
  • 在dispose中销毁控制器,避免内存泄漏

修改后的完整代码:

class HeightWidget extends StatefulWidget {
  const HeightWidget({
    required this.setHeight,
    required this.initialHeight,
    super.key,
  });

  final Function(double) setHeight;
  final int initialHeight;

  @override
  State<HeightWidget> createState() => _HeightWidgetState();
}

class _HeightWidgetState extends State<HeightWidget> {
  List<Widget> elements = [];
  late FixedExtentScrollController _scrollController;

  void fillWidget() {
    for (int i = 0; i < 230; i++) {
      elements.add(
        Align(
          alignment: Alignment.center,
          child: Text(i.toString()),
        ),
      );
    }
  }

  void setElement(int index) {
    widget.setHeight(index.toDouble() + 60);
  }

  @override
  void initState() {
    fillWidget();
    _scrollController = FixedExtentScrollController(initialItem: widget.initialHeight);
    super.initState();
  }

  @override
  void didUpdateWidget(covariant HeightWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.initialHeight != widget.initialHeight && widget.initialHeight == 0) {
      // 无动画直接跳转
      _scrollController.jumpToItem(0);
      // 如需动画效果,替换为下面的代码:
      // _scrollController.animateToItem(0, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut);
    }
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.all(10.0),
      padding: const EdgeInsets.all(3.0),
      decoration: BoxDecoration(
        border: Border.all(color: Colors.black),
        borderRadius: const BorderRadius.all(Radius.circular(15.0)),
      ),
      child: Column(
        children: [
          const SizedBox(height: 10.0),
          const HeaderWidget(title: "Height (in cm)"),
          Container(
            margin: const EdgeInsets.all(10.0),
            padding: const EdgeInsets.all(3.0),
            decoration: const BoxDecoration(
              color: kWeightBackgroundColor,
              borderRadius: BorderRadius.all(Radius.circular(25.0)),
            ),
            child: SizedBox(
              height: 100,
              child: ListWheelScrollViewX(
                scrollDirection: Axis.horizontal,
                physics: const FixedExtentScrollPhysics(),
                controller: _scrollController,
                itemExtent: 40,
                onSelectedItemChanged: (int index) {
                  setElement(index);
                },
                magnification: 1.5,
                useMagnifier: true,
                children: elements,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

关键说明:

  • didUpdateWidget:父组件更新当前Widget属性时会触发该方法,我们在此对比新旧initialHeight值,当新值为0时主动调用jumpToItem(0)强制滚动到起始位置。
  • 控制器复用:将控制器作为State成员变量,避免每次build创建新实例,保证滚动状态的连贯性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:42:42