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

Flutter无BuildContext的独立类中调用MovMapLocalizations多语言的方案

解决方案

步骤1:修正es.yaml的格式错误

你当前的es.yaml中signup、muro、time_ago节点缩进异常,比顶层的login多了4个前置空格,会导致yaml解析失败,先调整为和login同级的缩进,同时补充所有时间相关的翻译key:

login:
  email: Correo electrónico
  password: Contraseña
  login: Entrar
  signup: Registrar
  or: O
  newHere: ¿Nuevo aquí?

signup:
  email2: Correo electrónico
  password2: Contraseña
  login2: Entrar
  signup2: Registrar
  or2: O
  alreadyAccount: ¿Ya tienes cuenta de usuario?

muro:
  expand: leer más
  collapse: cerrar
  delete: Borrar
  denunciar: Denunciar
  already: Ya ha sido denunciado
  has_denunciado: Has denunciado este post

time_ago:
  yearsago: años atrás
  yearago: 1 año atrás
  last_year: El año pasado
  monthsago: meses atrás
  monthago: 1 mes atrás
  last_month: El mes pasado
  weeksago: semanas atrás
  weekago: 1 semana atrás
  last_week: La semana pasada
  daysago: días atrás
  dayago: 1 día atrás
  yesterday: Ayer
  hoursago: horas atrás
  hourago: 1 hora atrás
  an_hour_ago: Hace una hora
  minutesago: minutos atrás
  minuteago: 1 minuto atrás
  a_minute_ago: Hace un minuto
  secondsago: segundos atrás
  just_now: Ahora mismo

对应的en.yaml也补充完整time_ago相关key:

time_ago:
  yearsago: years ago
  yearago: 1 year ago
  last_year: Last year
  monthsago: months ago
  monthago: 1 month ago
  last_month: Last month
  weeksago: weeks ago
  weekago: 1 week ago
  last_week: Last week
  daysago: days ago
  dayago: 1 day ago
  yesterday: Yesterday
  hoursago: hours ago
  hourago: 1 hour ago
  an_hour_ago: An hour ago
  minutesago: minutes ago
  minuteago: 1 minute ago
  a_minute_ago: A minute ago
  secondsago: seconds ago
  just_now: Just now

步骤2:给MovMapLocalizations增加全局静态实例

修改MovMapLocalizations类,增加静态实例存储,本地化加载完成后自动赋值,后续不需要Context即可直接访问:

import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:yaml/yaml.dart';

class MovMapLocalizations {
  final String localeName;
  MovMapLocalizations(this.localeName);

  // 新增全局静态实例
  static MovMapLocalizations? _instance;
  static MovMapLocalizations get instance {
    assert(_instance != null, "MovMapLocalizations not initialized yet");
    return _instance!;
  }

  static const LocalizationsDelegate<MovMapLocalizations> delegate =
      _MovMapLocalizationsDelegate();

  YamlMap? translations;
  Future load() async {
    String yamlString = await rootBundle.loadString('lang/${localeName}.yml');
    translations = loadYaml(yamlString);
  }

  String t(String key) {
    try {
      var keys = key.split(".");
      dynamic translated = translations;
      for (var k in keys) {
        translated = translated?[k];
      }
      if (translated == null) {
        return "Key not found: $key";
      }
      return translated.toString();
    } catch (e) {
      return "Key not found: $key";
    }
  }
}

class _MovMapLocalizationsDelegate
    extends LocalizationsDelegate<MovMapLocalizations> {
  const _MovMapLocalizationsDelegate();
  @override
  bool isSupported(Locale locale) {
    print("@@@@@@@@@@@@@@@@@@@@@@@@@LOCALE ACTUAL:"+locale.languageCode);
    return ['es', 'en'].contains(locale.languageCode);
  }

  @override
  Future<MovMapLocalizations> load(Locale locale) async {
    var t = MovMapLocalizations(locale.languageCode);
    await t.load();
    // 加载完成后赋值给静态实例
    MovMapLocalizations._instance = t;
    return t;
  }

  @override
  bool shouldReload(covariant LocalizationsDelegate<MovMapLocalizations> old) {
    return false;
  }
}

步骤3:修改TimeAgo类调用全局翻译实例

直接通过MovMapLocalizations.instance.t()获取翻译文本即可,同时修复原代码中月份计算的逻辑错误:

class TimeAgo{

  String formatearFecha(Timestamp timestamp){
    var dateFromTimeStamp =
        DateTime.fromMillisecondsSinceEpoch(timestamp.seconds * 1000);
    return DateFormat('dd-MM-yyyy HH:mm').format(dateFromTimeStamp);
  }
   String timeAgoSinceDate(String dateString, {bool numericDates = true}) {
    DateTime date = DateTime.parse(dateString);
    final date2 = DateTime.now();
    final difference = date2.difference(date);
    final loc = MovMapLocalizations.instance;

    if ((difference.inDays / 365).floor() >= 2) {
      return '${(difference.inDays / 365).floor()} ${loc.t("time_ago.yearsago")}';
    } else if ((difference.inDays / 365).floor() >= 1) {
      return (numericDates) ? loc.t("time_ago.yearago") : loc.t("time_ago.last_year");
    } else if ((difference.inDays / 30).floor() >= 2) {
      return '${(difference.inDays / 30).floor()} ${loc.t("time_ago.monthsago")}';
    } else if ((difference.inDays / 30).floor() >= 1) {
      return (numericDates) ? loc.t("time_ago.monthago") : loc.t("time_ago.last_month");
    } else if ((difference.inDays / 7).floor() >= 2) {
      return '${(difference.inDays / 7).floor()} ${loc.t("time_ago.weeksago")}';
    } else if ((difference.inDays / 7).floor() >= 1) {
      return (numericDates) ? loc.t("time_ago.weekago") : loc.t("time_ago.last_week");
    } else if (difference.inDays >= 2) {
      return '${difference.inDays} ${loc.t("time_ago.daysago")}';
    } else if (difference.inDays >= 1) {
      return (numericDates) ? loc.t("time_ago.dayago") : loc.t("time_ago.yesterday");
    } else if (difference.inHours >= 2) {
      return '${difference.inHours} ${loc.t("time_ago.hoursago")}';
    } else if (difference.inHours >= 1) {
      return (numericDates) ? loc.t("time_ago.hourago") : loc.t("time_ago.an_hour_ago");
    } else if (difference.inMinutes >= 2) {
      return '${difference.inMinutes} ${loc.t("time_ago.minutesago")}';
    } else if (difference.inMinutes >= 1) {
      return (numericDates) ? loc.t("time_ago.minuteago") : loc.t("time_ago.a_minute_ago");
    } else if (difference.inSeconds >= 3) {
      return '${difference.inSeconds} ${loc.t("time_ago.secondsago")}';
    } else {
      return loc.t("time_ago.just_now");
    }
  }
}

注意事项

确保调用TimeAgo的方法时,APP已经完成本地化初始化(即runApp执行后,本地化Delegate的load方法已经执行完成),正常业务场景下用户能触发时间计算逻辑时,本地化都已经加载完毕。如果需要在APP启动极早期就调用TimeAgo,可以提前判断MovMapLocalizations._instance是否为空,为空的话先手动初始化默认语言的实例即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:48:03