String xml file in Flutter

后端 未结 7 1875
难免孤独
难免孤独 2021-02-01 15:18

In flutter string text are directly set to the TextField widget like:

new Text(\'Hello,  How are you?\')

Is correct way ? or we ca

相关标签:
7条回答
  • 2021-02-01 15:27
      create "Strings.dart" file and add the below line==>
    
    
     class Strings
     {
          static String welcomeScreen="WelCome Page";
          static String loadingMessage="Loading Please Wait...!";
     }
    
     And then call the file using the below line using the widget
     Text(Strings.loadingMessage)
    
     Make sure that the String.dart file has been imported
    
    0 讨论(0)
  • 2021-02-01 15:30

    Flutter currently doesn’t have a dedicated resources-like system for strings. At the moment, the best practice is to hold your copy text in a class as static fields and accessing them from there. For example:

    class Strings {
      static const String welcomeMessage = "Welcome To Flutter";
    }
    

    Then in your code, you can access your strings as such:

    Text(Strings.welcomeMessage)
    

    source


    Edit May '19:

    There's now this package that allows you to create json files with your Strings. It will allow you to create Strings for plurals, genders and languages etc

    You can create a separate json file for each language like so:

    string_en.json

    {
    "thanks": "Thanks."
    }
    

    string_nl.json

    {    
    "thanks": "Dankjewel."
    }
    

    And then use this to access it

    S.of(context).thanks;
    

    It will know which language to choose based on your phone's default language.

    0 讨论(0)
  • 2021-02-01 15:31

    For those of you who don't want to use any 3rd party plugin, here is how you can do it.

    1. Create a folder strings in assets. Put your language file in it.

      assets
        strings
        - en.json // for english 
        - ru.json  // for russian
      
    2. Now in en.json, write your string, for example.

      {
        "text1": "Hello",
        "text2": "World"
      }
      

      Similarly, in ru.json,

      {
        "text1": "Привет",
        "text2": "Мир"
      }
      
    3. Add this to pubspec.yaml file (mind the spaces)

      flutter:
      
        uses-material-design: true
      
        assets:
          - assets/strings/en.json
          - assets/strings/ru.json
      
    4. Now you are all set to use these strings in your app. Here is the sample code, the AppBar shows the translated text.

      void main() {
        runApp(
          MaterialApp(
            locale: Locale("ru"), // switch between en and ru to see effect
            localizationsDelegates: [const DemoLocalizationsDelegate()],
            supportedLocales: [const Locale('en', ''), const Locale('ru', '')],
            home: HomePage(),
          ),
        );
      }
      
      class HomePage extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(title: Text(DemoLocalizations.of(context).getText("text2") ?? "Error")),
          );
        }
      }
      
      // this class is used for localizations
      class DemoLocalizations {
        static DemoLocalizations of(BuildContext context) {
          return Localizations.of<DemoLocalizations>(context, DemoLocalizations);
        }
      
        String getText(String key) => language[key];
      }
      
      Map<String, dynamic> language;
      
      class DemoLocalizationsDelegate extends LocalizationsDelegate<DemoLocalizations> {
        const DemoLocalizationsDelegate();
      
        @override
        bool isSupported(Locale locale) => ['en', 'ru'].contains(locale.languageCode);
      
        @override
        Future<DemoLocalizations> load(Locale locale) async {
          String string = await rootBundle.loadString("assets/strings/${locale.languageCode}.json");
          language = json.decode(string);
          return SynchronousFuture<DemoLocalizations>(DemoLocalizations());
        }
      
        @override
        bool shouldReload(DemoLocalizationsDelegate old) => false;
      }
      
    0 讨论(0)
  • 2021-02-01 15:31

    You can use the methods represented in the internationalization sections of the documentation to control both centralized string management and translations (if you need translations)

    https://flutter.io/tutorials/internationalization/

    It might be overkill for a simple app with only a few strings though.

    0 讨论(0)
  • 2021-02-01 15:33

    I would separate these classes into individual files, but just to explain my approach for this question.

    I have a base class which has my strings getters. Each language I want to support I have to create a class which extends from this class and override its getters. Thus, whenever I create a string, I have to override in each implementation of this base class. It is helpful to avoid forgetting create some locale specific string.

    /// Interface strings
    class Strings {
    
      String get hello;
    }
    
    
    /// English strings
    class StringsEnglish extends Strings {
       
      @override
      String get hello => 'Hello';
    }
    
    /// Russian strings
    class StringsRussian extends Strings {
      @override
      String get hello => 'Привет';
    }
    
    /// Portuguese strings
    class StringsPortuguese extends Strings {
      @override
      String get hello => 'Olá';
    }
    

    After that, in a global scope of your application, you could declare a unique instance of the locale you want to use (using a singleton is a good option).

    Just showing a short example of using it:

     class Resources {
      BuildContext _context;
    
      Resources(this._context);
    
      Strings get strings {
        // It could be from the user preferences or even from the current locale
        Locale locale = Localizations.localeOf(_context);
        switch (locale.languageCode) {
          case 'pt':
            return StringsPortuguese();
          case 'ru':
            return StringsRussian();
          default:
            return StringsEnglish();
        }
      }
    
      static Resources from(BuildContext context){
        return Resources(context);
      }
    }
    

    And finally, using it in some widget:

    Text(Resources.from(context).strings.hello)
    

    Using an extension from BuildContext

    You can extend BuildContext to create some particular features and give more power to your application. This is available from Dart 2.7. See more.

    app_context_extension.dart

    extension AppContext on BuildContext {
    
      Resources get resources => Resources.from(this);
    
    }
    

    favorites_page.dart

    import 'package:flutter/material.dart';
    // you have to import it yourself. The auto import does not work in this case
    import 'package:myapp/ui/extensions/app_context_extension.dart';
    
    class FavoritesPage extends StatefulWidget {
      @override
      _FavoritesPageState createState() => _FavoritesPageState();
    }
    
    class _FavoritesPageState extends State<FavoritesPage> {
      @override
      Widget build(BuildContext context) {
        return Text(context.resources.strings.hello);
      }
    }
    

    Using GlobalKey

    Along with an extension of BuildContext as shown above, you can also use GlobalKey. Basically, you could use it when you do not have a context instance. This last one has a good advantage. You could use strings anywhere in your application. In other words, if you use some pattern like MVC for instance and want to use strings in your controllers, you could easily do it.

    You can declare something like this:

    application.dart

    import 'package:myapp/ui/extensions/app_context_extension.dart';
    import 'package:myapp/ui/values/resources.dart';
    import 'package:flutter/material.dart';
    
    class Application {
      static GlobalKey<NavigatorState> navKey = GlobalKey();
    
      static Resources get resources {
        return navKey.currentContext.resources;
      }
    }
    

    main.dart

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          navigatorKey: Application.navKey,
    ...
    

    And then:

    import 'package:flutter/material.dart';
    import 'package:myapp/application/application.dart';
    
    class FavoritesPage extends StatefulWidget {
      @override
      _FavoritesPageState createState() => _FavoritesPageState();
    }
    
    class _FavoritesPageState extends State<FavoritesPage> {
      @override
      Widget build(BuildContext context) {
        return Text(Application.resources.strings.hello);
      }
    }
    

    Hope it helps!

    0 讨论(0)
  • 2021-02-01 15:39

    I use this method instead of using third party lib. Basically, I create a class that holds those values (string, colors, dimens, etc)

    resources.dart

    import 'dart:ui';
    
    class ResString{
      var data = {
        'url' : 'https://facebook.com/',
        'welcome' : 'Welcome Home',
      };
    
      String get(String key){
        return data[key];
      }
    }
    
    class ResColor{
      var data = {
        'colorPrimary' : 0xff652A04,
        'colorPrimaryDark' : 0xffFFFFFF,
        'colorPrimaryLight' : 0xffF6EDDD,
      };
    
      Color get(String key){
        return Color(data[key]);
      }
    }
    

    To use it, simply call the get method

    main.dart

    import 'package:my_app/resources.dart';
    ...
        return Container(
          color: ResColor().get('colorPrimary')
        );
    ...
    
    0 讨论(0)
提交回复
热议问题