简体   繁体   English

Flutter:如何翻译 BottomNavigationBarItem 上的选项卡

[英]Flutter: how to translate tabs on BottomNavigationBarItem

I'm new to Flutter (and the Dart programming language) and I'm struggling with translating the tabs on the BottomNavigationBarItem .我是Flutter (和Dart编程语言)的新手,我正在努力翻译BottomNavigationBarItem上的选项卡。 I'm currently basing my code heavily on Andrea Bizzotto's Bottom Navigation Bar with Multiple Navigators .我目前的代码主要基于 Andrea Bizzotto 的带有多个导航器的底部导航栏

Here's what I have so far:这是我到目前为止所拥有的:

Setup:设置:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'CovidSafe extended',
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const <Locale>[
        Locale('nl'),
        Locale('fr'),
        Locale('de'),
        Locale('en'),
      ],
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const App(),
    );
  }
}

class App extends StatefulWidget {
  const App({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => AppState();
}

class AppState extends State<App> {
  var _currentTab = TabItem.red;
  final _navigatorKeys = {
    TabItem.red: GlobalKey<NavigatorState>(),
    TabItem.green: GlobalKey<NavigatorState>(),
    TabItem.blue: GlobalKey<NavigatorState>(),
  };

  ...
}

It uses a TabItem object, which is an enumerable, which has 2 properties: tabName and activeTabColor :它使用 TabItem object,它是一个可枚举的,具有 2 个属性: tabNameactiveTabColor

enum TabItem { red, green, blue }

const Map<TabItem, String> tabName = {
  TabItem.red: 'red',
  TabItem.green: 'green',
  TabItem.blue: 'blue',
};

const Map<TabItem, MaterialColor> activeTabColor = {
  TabItem.red: Colors.red,
  TabItem.green: Colors.green,
  TabItem.blue: Colors.blue,
};

The navbar items get built from the _buildItem function inside the BottomNavigation class, like so:导航栏项目是从_buildItem class 内的BottomNavigation function 构建的,如下所示:

class BottomNavigation extends StatelessWidget {
  const BottomNavigation(
      {Key? key, required this.currentTab, required this.onSelectTab})
      : super(key: key);
  final TabItem currentTab;
  final ValueChanged<TabItem> onSelectTab;

  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      type: BottomNavigationBarType.fixed,
      items: [
        _buildItem(TabItem.red, context),
        _buildItem(TabItem.green, context),
        _buildItem(TabItem.blue, context),
      ],
      onTap: (index) => onSelectTab(
        TabItem.values[index],
      ),
      currentIndex: currentTab.index,
      selectedItemColor: activeTabColor[currentTab]!,
    );
  }

  BottomNavigationBarItem _buildItem(TabItem tabItem, BuildContext context) {
    return BottomNavigationBarItem(
      icon: Icon(
        Icons.layers,
        color: _colorTabMatching(tabItem),
      ),
      // I think this is where I need to somehow translate the tabName 
      label: tabName[tabItem],
    );
  }

  Color _colorTabMatching(TabItem item) {
    return currentTab == item ? activeTabColor[item]! : Colors.grey;
  }
}

I've tried using the following code to translate the label/tabName:我尝试使用以下代码来翻译标签/标签名称:

// Option 1:
// won't work because "there's no getter for tabName"
label: AppLocalizations.of(context)!.tabName[tabItem],
// Option 2:
// tried some variants of this, this will just print "AppLocalizations.of..." as a string
label: '$AppLocalizations.of($context)!.$tabName[$tabItem]',
// Option 3:
label: AppLocalizations.of(context)!.bottomNavBarLabel(tabName[tabItem])
// and added the following to my `app_en.arb` file:
"bottomNavBarLabel": "{label}",
"@bottomNavBarLabel": {
    "type": "text",
    "placeholders": {
        "label": {}
    }
},
// but that doesn't actually translate the variable passed along (which does makes sense, but I figured I'd at least try it)

I've also tried passing the BuildContext along to the TabName Map , but couldn't get it to work.我也尝试将BuildContext传递给TabName Map ,但无法使其正常工作。

I'm sure this is something relatively simple that I just can seem to figure out.我确信这是相对简单的事情,我似乎可以弄清楚。 Maybe working with a Map is actually not the way to go for this, I don't know...也许使用Map实际上不是 go 的方式,我不知道......

So how do I make it so that the label ( tabName[tabItem] ) is translatable?那么如何使label ( tabName[tabItem] ) 可翻译?

In my personal experience so far, you don't change the labels through passing data between widgets (not that you can't, but IMHO this is much more easier and pragmatic, since the user can have an app in his native language, if you support it that is, without having to change the apps language inside the app settings), but with locale language that is detected through app localization/internationalization .到目前为止,根据我的个人经验,您不会通过在小部件之间传递数据来更改标签(并不是您不能,但恕我直言,这更容易和务实,因为用户可以使用他的母语使用应用程序,如果您支持它,即无需更改应用程序设置中的应用程序语言),但使用通过应用程序本地化/国际化检测到的区域设置语言。 You might wanna try a few things.你可能想尝试一些东西。 First, try adding this callback in your MaterialApp() :首先,尝试在您的MaterialApp()中添加此回调:

localeResolutionCallback: (locale, supportedLocales) {
          for (var supportedLocale in supportedLocales) {
            if (supportedLocale.languageCode == locale.languageCode &&
                supportedLocale.countryCode == locale.countryCode) {
              return supportedLocale;
            }
          }

          return supportedLocales.first;
        },

Here is where you check if the current locale is supported in your app, if it is, change the text to your locale.您可以在此处检查您的应用程序是否支持当前语言环境,如果支持,请将文本更改为您的语言环境。

If you haven't yet, in your lib folder create a new folder called l10n, and add a file app_en.arb where you can define the text you wanna change in English.如果您还没有,请在您的lib文件夹中创建一个名为 l10n 的新文件夹,并添加一个文件app_en.arb ,您可以在其中定义您想用英语更改的文本。 Then do the same with another file, I made one for German, so app_de.arb .然后对另一个文件做同样的事情,我为德语做了一个,所以app_de.arb In those files, define the text you wish to change throughout the app with locale language change: app_en.arb在这些文件中,使用区域设置语言更改定义您希望在整个应用程序中更改的文本:app_en.arb

{
  "@@locale": "en",

  "hello": "Hello",
  "@hello": {
    "description": "The conventional newborn programmer greeting"
  },
}

You do the same for German (or any other language for that matter) but you only define the main EN you wish to change:你对德语(或任何其他语言)做同样的事情,但你只定义你想改变的主要 EN:

{
  "@@locale": "de",

  "hello": "Hallo", // from English to German
}

Then you define where is the text you want to change with:然后定义要更改的文本在哪里:

AppLocalizations.of(context).hello // here you define the word you want to change on app locale change

If this doesn't work, let me know and I will try to find another solution for you.如果这不起作用,请告诉我,我会尝试为您找到另一种解决方案。 Cheers!干杯!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM