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

Flutter应用恢复时如何获取设备设置中的最新时间格式

问题原因

这是Flutter的MediaQuery内部缓存机制导致的。当你在后台修改系统时间格式后,应用第一次恢复时,Flutter框架还没来得及同步更新MediaQuery中存储的系统配置缓存,所以MediaQuery.of(context).alwaysUse24HourFormat返回的还是旧的设置值;第二次恢复时,缓存已经完成更新,自然能拿到正确的时间格式配置。

解决方案

提供两种可行的解决方法:

方法一:延迟到帧绘制完成后获取

在应用恢复到前台时,等待当前帧绘制完成后再获取MediaQuery数据,此时框架已经完成了系统配置的同步更新:

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  super.didChangeAppLifecycleState(state);
  if (state == AppLifecycleState.resumed) {
    // 等待当前帧结束后再读取最新配置
    WidgetsBinding.instance.addPostFrameCallback((_) {
      bool is24Hours = MediaQuery.of(context).alwaysUse24HourFormat;
      // 在这里更新你的时间显示逻辑
    });
  }
}

方法二:让Widget自动监听MediaQuery变化

如果你的UI直接依赖时间格式配置,可以在build方法中直接读取MediaQuery.of(context).alwaysUse24HourFormat,MediaQuery本身是可监听的,当系统配置变化时,Widget会自动重建并获取最新值:

@override
Widget build(BuildContext context) {
  bool is24Hours = MediaQuery.of(context).alwaysUse24HourFormat;
  return Scaffold(
    body: Center(
      child: Text(is24Hours ? "当前为24小时制" : "当前为12小时制"),
    ),
  );
}

这种方式下,你依然可以保留生命周期监听,但不需要额外的Timer调用,框架会自动处理配置更新。

另外,你原代码中通过Timer手动调用didChangeAppLifecycleState的操作是多余的,WidgetsBinding会在应用状态变化时自动触发这个回调,建议删除这段Timer代码。

额外方案(非Widget环境下)

如果需要在非Widget上下文(比如业务逻辑层)获取时间格式,可以结合dart:ui的window和intl包来判断,同样建议在resumed状态下延迟获取:

import 'dart:ui';
import 'package:intl/intl.dart';

bool getIs24HourFormat() {
  final locale = window.locale;
  final timeFormat = DateFormat.Hm(locale.toString());
  return timeFormat.pattern.contains('H');
}

// 在resumed中使用
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  super.didChangeAppLifecycleState(state);
  if (state == AppLifecycleState.resumed) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      bool is24Hours = getIs24HourFormat();
      // 处理逻辑
    });
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 12:35:21