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.
相关产品推荐
相关产品推荐

