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

Flutter如何实现支持kg/lbs切换与数值同步换算的Cupertino重量选择器

代码调整方案

核心思路

统一以千克为基准存储选中重量,单位切换时自动换算为当前单位的数值,同时动态切换重量选择器的展示列表、同步选中位置。

具体修改步骤

1. 调整变量定义

// 重量换算常量
const double kgToLbFactor = 2.20462;
// 基准存储:始终存千克单位的重量,初始值对应你原来的150lb
double _selectedWeightInKg = 68.0;
var _selectedUnits = "lbs";
var units = ['kgs', 'lbs'];
var lbs = [];
var kgs = []; 
// 重量选择器控制器,用于单位切换时自动滚动到对应数值位置
FixedExtentScrollController? _weightPickerController;

2. 修改initState初始化逻辑

@override
void initState() {
  super.initState();
  for (int j = 22; j <= 227; j++) {
    kgs.add(j);
    // 磅数值保留1位小数,可按需调整精度
    lbs.add((j * kgToLbFactor).toStringAsFixed(1));
  }
  // 初始化控制器,默认选中当前单位对应重量的索引
  _weightPickerController = FixedExtentScrollController(
    initialItem: _getTargetWeightIndex(),
  );
}

// 工具方法:计算当前单位下选中重量对应的列表索引
int _getTargetWeightIndex() {
  if (_selectedUnits == 'kgs') {
    return kgs.indexOf(_selectedWeightInKg.round());
  } else {
    double targetLb = _selectedWeightInKg * kgToLbFactor;
    // 匹配最接近的磅数值索引
    return lbs.indexWhere((lbVal) => double.parse(lbVal) >= targetLb);
  }
}

// 工具方法:获取当前单位下要显示的重量数值
double get currentDisplayWeight {
  return _selectedUnits == 'kgs' ? _selectedWeightInKg : _selectedWeightInKg * kgToLbFactor;
}

3. 替换重量选择器逻辑

将原来的第一个CupertinoPicker(重量选择部分)替换为如下代码:

Expanded(
  child: CupertinoPicker(
    controller: _weightPickerController,
    itemExtent: 32,
    onSelectedItemChanged: (int index) {
      setState(() {
        if (_selectedUnits == 'kgs') {
          _selectedWeightInKg = kgs[index].toDouble();
        } else {
          _selectedWeightInKg = double.parse(lbs[index]) / kgToLbFactor;
        }
      });
    },
    children: List<Widget>.generate(
      _selectedUnits == 'kgs' ? kgs.length : lbs.length,
      (int index) {
        return Center(
          child: Text(
            _selectedUnits == 'kgs' ? kgs[index].toString() : lbs[index].toString()
          ),
        );
      },
    ),
  ),
),

4. 修改单位选择器的切换逻辑

将原来的第二个CupertinoPicker(单位选择部分)的onSelectedItemChanged回调修改为:

onSelectedItemChanged: (int index) {
  setState(() {
    _selectedUnits = units[index];
    // 切换单位后自动滚动到换算后的重量对应位置
    _weightPickerController?.jumpToItem(_getTargetWeightIndex());
  });
},

5. 修改显示文本

将按钮上的展示文本替换为:

Text(
  // 保留1位小数显示,可按需调整精度
  '${currentDisplayWeight.toStringAsFixed(1)} $_selectedUnits',
  style: const TextStyle(
    height: 1,
    color: Colors.black,
    fontSize: 16,
  ),
),

额外说明

原来代码中写在onSelectedItemChanged回调里的Form校验逻辑无效,Text组件放在回调函数中不会渲染到页面,需要校验可统一在提交表单时处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 08:36:03