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

如何像Flutter本地化与主题切换那样实现单位(C、F、K)切换?

最简实现Flutter计量单位切换方案

和切换暗黑模式、语言的思路一致,核心是全局状态管理+组件自动响应更新,无需给每个文本手动添加监听器。下面是具体实现步骤:

1. 定义计量单位枚举

先明确支持的温度单位类型:

enum TemperatureUnit {
  celsius,
  fahrenheit,
  kelvin,
}

2. 创建状态管理类

用ChangeNotifier封装当前选中单位、切换逻辑和温度转换方法,让所有需要转换的地方复用统一逻辑:

import 'package:flutter/foundation.dart';

class UnitSettings extends ChangeNotifier {
  TemperatureUnit _currentUnit = TemperatureUnit.celsius;

  TemperatureUnit get currentUnit => _currentUnit;

  // 切换单位并通知组件更新
  void switchUnit(TemperatureUnit newUnit) {
    _currentUnit = newUnit;
    notifyListeners();
  }

  // 将原始摄氏度值转为当前单位的显示文本
  String convertTemperature(double celsiusValue) {
    double converted;
    String suffix;

    switch (_currentUnit) {
      case TemperatureUnit.celsius:
        converted = celsiusValue;
        suffix = '°C';
        break;
      case TemperatureUnit.fahrenheit:
        converted = celsiusValue * 9/5 + 32;
        suffix = '°F';
        break;
      case TemperatureUnit.kelvin:
        converted = celsiusValue + 273.15;
        suffix = 'K';
        break;
    }

    return '${converted.toStringAsFixed(1)}$suffix';
  }
}

3. 在应用顶层注入状态

用ChangeNotifierProvider把状态类挂载到应用根节点,让所有子组件都能访问状态:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => UnitSettings(),
      child: const MyApp(),
    ),
  );
}

4. 组件中自动响应状态变化

在需要显示温度的地方,用Consumer监听状态变化,自动更新UI:

// 示例温度显示组件
class TemperatureDisplay extends StatelessWidget {
  final double celsiusTemp;

  const TemperatureDisplay({super.key, required this.celsiusTemp});

  @override
  Widget build(BuildContext context) {
    return Consumer<UnitSettings>(
      builder: (context, unitSettings, child) {
        return Text(
          unitSettings.convertTemperature(celsiusTemp),
          style: const TextStyle(fontSize: 24),
        );
      },
    );
  }
}

5. 实现单位切换UI

用下拉菜单或按钮组触发单位切换操作:

class UnitSwitcher extends StatelessWidget {
  const UnitSwitcher({super.key});

  @override
  Widget build(BuildContext context) {
    final unitSettings = Provider.of<UnitSettings>(context, listen: false);

    return DropdownButton<TemperatureUnit>(
      value: unitSettings.currentUnit,
      items: const [
        DropdownMenuItem(
          value: TemperatureUnit.celsius,
          child: Text('摄氏度'),
        ),
        DropdownMenuItem(
          value: TemperatureUnit.fahrenheit,
          child: Text('华氏度'),
        ),
        DropdownMenuItem(
          value: TemperatureUnit.kelvin,
          child: Text('开尔文'),
        ),
      ],
      onChanged: (newUnit) {
        if (newUnit != null) {
          unitSettings.switchUnit(newUnit);
        }
      },
    );
  }
}

方案优势

  • 贴合Flutter原生Theme、Localizations的设计思路,符合框架使用习惯
  • 全局状态统一管理,一次切换操作即可触发所有关联组件自动更新
  • 转换逻辑集中封装,后续扩展新单位只需修改状态类,无需改动业务组件
  • 用Consumer精准监听状态变化,性能开销远低于手动添加监听器

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 22:30:03