如何在Flutter中对列表应用AppLocalizations本地化?
Flutter 字符串列表本地化解决方案
方案一:在列表构建时通过key映射获取本地化字符串
无需修改现有ProfileItems结构,直接在ListView.builder的itemBuilder中,根据列表项的title key匹配对应的本地化字符串。
实现代码:
ListView.builder( itemCount: items.length, padding: EdgeInsets.zero, physics: NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (context, index) { final localizations = AppLocalizations.of(context)!; String localizedTitle; // 根据key映射对应本地化字符串 switch(items[index].title) { case "myFav": localizedTitle = localizations.myFav; break; case "myColec": localizedTitle = localizations.myColec; break; case "myPurchase": localizedTitle = localizations.myPurchase; break; case "myGift": localizedTitle = localizations.myGift; break; case "myPref": localizedTitle = localizations.myPref; break; default: localizedTitle = items[index].title; // 匹配失败时回显原key } return Column( children: [ Container( height: 40, margin: EdgeInsets.symmetric(horizontal: 8), child: Center( child: ListTile( minLeadingWidth: 10, visualDensity: VisualDensity(horizontal: 0, vertical: -4), leading: SvgPicture.asset( items[index].iconName, fit: BoxFit.cover, color: themeController.theme.cardColor, ), title: AppText.appText( localizedTitle, // 传入本地化后的字符串 fontFamily: true, fontSize: 14, fontWeight: FontWeight.normal, textColor: themeController.theme.cardColor, ), trailing: Icon( Icons.navigate_next_outlined, color: themeController.theme.cardColor, ), ), ), ), const Divider( indent: 8, endIndent: 8, thickness: 1, ), ], ); }, );
方案二:修改ProfileItems结构,存储本地化字符串获取函数
通过调整ProfileItems的字段类型,让title直接关联本地化逻辑,后续扩展更灵活。
步骤1:修改ProfileItems类
class ProfileItems { final String iconName; final String Function(BuildContext) title; // 改为接收BuildContext的函数类型 ProfileItems({required this.iconName, required this.title}); }
步骤2:初始化本地化列表
List<ProfileItems> items = [ ProfileItems(iconName: AppImage.heart, title: (context) => AppLocalizations.of(context)!.myFav), ProfileItems(iconName: AppImage.save_collection, title: (context) => AppLocalizations.of(context)!.myColec), ProfileItems(iconName: AppImage.my_purchases, title: (context) => AppLocalizations.of(context)!.myPurchase), ProfileItems(iconName: AppImage.my_gifts, title: (context) => AppLocalizations.of(context)!.myGift), ProfileItems(iconName: AppImage.preferences, title: (context) => AppLocalizations.of(context)!.myPref), ];
步骤3:在itemBuilder中调用函数获取字符串
ListView.builder( itemCount: items.length, padding: EdgeInsets.zero, physics: NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (context, index) { final localizedTitle = items[index].title(context); return Column( children: [ Container( height: 40, margin: EdgeInsets.symmetric(horizontal: 8), child: Center( child: ListTile( minLeadingWidth: 10, visualDensity: VisualDensity(horizontal: 0, vertical: -4), leading: SvgPicture.asset( items[index].iconName, fit: BoxFit.cover, color: themeController.theme.cardColor, ), title: AppText.appText( localizedTitle, fontFamily: true, fontSize: 14, fontWeight: FontWeight.normal, textColor: themeController.theme.cardColor, ), trailing: Icon( Icons.navigate_next_outlined, color: themeController.theme.cardColor, ), ), ), ), const Divider( indent: 8, endIndent: 8, thickness: 1, ), ], ); }, );
方案三:利用intl生成类的lookup方法(仅适用于intl本地化)
如果你的AppLocalizations是通过intl包自动生成的,类中会自带lookup方法,可直接通过key字符串获取本地化值:
ListView.builder( itemCount: items.length, padding: EdgeInsets.zero, physics: NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (context, index) { final localizations = AppLocalizations.of(context)!; final localizedTitle = localizations.lookup(items[index].title); return Column( children: [ Container( height: 40, margin: EdgeInsets.symmetric(horizontal: 8), child: Center( child: ListTile( minLeadingWidth: 10, visualDensity: VisualDensity(horizontal: 0, vertical: -4), leading: SvgPicture.asset( items[index].iconName, fit: BoxFit.cover, color: themeController.theme.cardColor, ), title: AppText.appText( localizedTitle, fontFamily: true, fontSize: 14, fontWeight: FontWeight.normal, textColor: themeController.theme.cardColor, ), trailing: Icon( Icons.navigate_next_outlined, color: themeController.theme.cardColor, ), ), ), ), const Divider( indent: 8, endIndent: 8, thickness: 1, ), ], ); }, );
注意:需确保列表中的title key与intl配置文件中的key完全一致,否则会回显默认值或抛出错误。
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

