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

如何构建带int回调的可滚动Widget,实现体重选择滚动刻度器?

Flutter 体重选择滚动刻度器实现方案

核心实现思路

用ListWheelScrollView构建滚轮式选择器,自带中间项放大效果,匹配需求中的UI样式;通过滚动控制器监听滚动停止事件,计算当前选中的体重值并触发int类型回调。

完整代码实现

import 'package:flutter/material.dart';

class WeightPicker extends StatefulWidget {
  // 滚动停止时触发的体重选中回调
  final ValueChanged<int> onWeightSelected;
  // 初始选中体重
  final int initialWeight;
  // 最小可选体重
  final int minWeight;
  // 最大可选体重
  final int maxWeight;

  const WeightPicker({
    super.key,
    required this.onWeightSelected,
    this.initialWeight = 60,
    this.minWeight = 30,
    this.maxWeight = 150,
  });

  @override
  State<WeightPicker> createState() => _WeightPickerState();
}

class _WeightPickerState extends State<WeightPicker> {
  late FixedExtentScrollController _scrollController;

  @override
  void initState() {
    super.initState();
    // 初始化滚动控制器,定位到初始体重对应的索引
    _scrollController = FixedExtentScrollController(
      initialItem: widget.initialWeight - widget.minWeight,
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return NotificationListener<ScrollEndNotification>(
      // 监听滚动停止事件
      onNotification: (notification) {
        final selectedIndex = _scrollController.selectedItem;
        final selectedWeight = widget.minWeight + selectedIndex;
        // 触发体重选中回调
        widget.onWeightSelected(selectedWeight);
        return true;
      },
      child: ListWheelScrollView.useDelegate(
        controller: _scrollController,
        // 每个选项的高度
        itemExtent: 60,
        // 开启中间项放大效果
        useMagnifier: true,
        // 放大倍数
        magnification: 1.3,
        // 选项之间的挤压程度
        squeeze: 1.2,
        childDelegate: ListWheelChildBuilderDelegate(
          builder: (context, index) {
            final weight = widget.minWeight + index;
            return Center(
              child: Text(
                '$weight kg',
                style: const TextStyle(
                  fontSize: 24,
                  fontWeight: FontWeight.w500,
                ),
              ),
            );
          },
          // 计算选项总数
          childCount: widget.maxWeight - widget.minWeight + 1,
        ),
      ),
    );
  }
}

使用示例

在父Widget中直接调用即可:

WeightPicker(
  onWeightSelected: (selectedWeight) {
    // 处理选中体重后的逻辑,比如更新状态、提交数据等
    print('当前选中体重:$selectedWeight kg');
  },
  initialWeight: 65,
  minWeight: 40,
  maxWeight: 120,
)

关键说明

  • ListWheelScrollView的useMagnifier和magnification属性实现了中间选项放大的视觉效果,和预期UI一致
  • FixedExtentScrollController用于精准控制滚动位置,获取当前选中项的索引
  • NotificationListener<ScrollEndNotification>确保只在滚动完全停止后触发回调,避免滚动过程中的频繁触发
  • 支持自定义最小/最大体重和初始选中值,适配不同场景需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 00:46:09