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

Flutter中如何将Intl的select配置转为Dart列表?

Flutter本地化中读取YouTube视频ID列表失败的解决方法

问题场景

在Flutter应用中使用youtube_player_iframe插件展示多语言YouTube视频,通过intl插件将视频ID存入.arb本地化文件的select结构中。尝试读取该内容并通过正则转为Dart列表时,获取到的结果是闭包描述字符串,而非预期的本地化内容。

相关代码与配置

.arb文件配置:

"youtubeVideo": "{choice, select, 1{W6wIEp-M4tg} 2{bXOr0G7v-9Q} 3{zFWdTv6-7ws} 4{z8oSo6qTmqk} 5{_d29LTKgCEA} 6{PH8Mmxxhq_E} other{}}",
"@youtubeVideo": {
  "placeholders": {
    "choice": {}
  }
}

错误的读取代码:

RegExp exp = RegExp(r'^[\w\W]+$');
String str = AppLocalizations.of(context)!.youtubeVideo.toString();
RegExpMatch? match = exp.firstMatch(str);

错误结果:

Closure: (String) => String from Function 'youtubeVideo':.

原因分析

intl插件会将.arb中的select类型字段生成为带参数的函数(例如String youtubeVideo(String choice)),而非直接的字符串。直接调用youtubeVideo而不传参数,得到的是函数对象,调用toString()自然会输出闭包的描述信息。

解决方案

方案一:直接读取arb文件提取所有视频ID

如果需要提取所有语言对应的视频ID列表,可以直接读取.arb文件内容,再用正则匹配提取:

  1. 在pubspec.yaml中添加arb文件为资产:
flutter:
  assets:
    - assets/l10n/app_en.arb  # 替换为你的英文arb路径
    - assets/l10n/app_zh.arb  # 替换为你的中文arb路径
  1. 读取文件并提取ID的代码:
import 'package:flutter/services.dart';
import 'dart:convert';
import 'package:flutter/widgets.dart';

Future<List<String>> getYoutubeVideoIds(BuildContext context) async {
  // 获取当前语言代码
  String localeCode = Localizations.localeOf(context).languageCode;
  // 拼接对应语言的arb文件路径
  String arbPath = 'assets/l10n/app_$localeCode.arb';
  
  // 读取arb文件内容
  String arbContent = await rootBundle.loadString(arbPath);
  Map<String, dynamic> arbData = jsonDecode(arbContent);
  String videoSelectStr = arbData['youtubeVideo'] as String;
  
  // 正则匹配所有数字标记后的视频ID
  RegExp idRegex = RegExp(r'\d+\{([a-zA-Z0-9_-]+)\}');
  Iterable<RegExpMatch> matches = idRegex.allMatches(videoSelectStr);
  
  // 提取并返回ID列表
  return matches.map((match) => match.group(1)!).toList();
}

方案二:优化arb存储结构(更推荐)

放弃select结构,直接用分隔符分隔的字符串存储视频ID,简化读取逻辑:

  1. 修改arb文件配置:
"youtubeVideos": "W6wIEp-M4tg,bXOr0G7v-9Q,zFWdTv6-7ws,z8oSo6qTmqk,_d29LTKgCEA,PH8Mmxxhq_E",
"@youtubeVideos": {
  "description": "Comma-separated list of YouTube video IDs"
}
  1. 读取并转为列表的代码:
List<String> videoIds = AppLocalizations.of(context)!.youtubeVideos.split(',');

如果需要同时支持根据索引获取单个视频ID,可以直接通过列表索引访问:

String getVideoByIdx(int idx) {
  List<String> ids = AppLocalizations.of(context)!.youtubeVideos.split(',');
  return idx >= 0 && idx < ids.length ? ids[idx] : '';
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:22:39