String-XML-Datei in Flutter

Lesezeit: 8 Minuten

Benutzeravatar von Magesh Pandian
Magesh Pandian

Bei Flutter werden die Stringtexte direkt gesetzt TextField Widget wie:

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

Ist der richtige Weg? oder wir können alle Zeichenfolgen in einer Datei verwalten und wie folgt verwenden:

<string name="name_hint">Hello, How are you?</string>

Ist es möglich ?

Benutzeravatar von MSpeed
MSpeed

Flutter hat derzeit kein dediziertes Ressourcen-ähnliches System für Strings. Im Moment ist es am besten, Ihre Textkopien in einer Klasse als statische Felder zu halten und von dort aus darauf zuzugreifen. Zum Beispiel:

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

Dann können Sie in Ihrem Code auf Ihre Zeichenfolgen als solche zugreifen:

Text(Strings.welcomeMessage)

Quelle


Bearbeiten Mai ’19:

Es gibt jetzt dieses Paket Damit können Sie JSON-Dateien mit Ihren Strings erstellen. Es ermöglicht Ihnen, Zeichenfolgen für Pluralformen, Geschlechter und Sprachen usw. zu erstellen

Sie können für jede Sprache eine separate JSON-Datei wie folgt erstellen:

string_en.json

{
"thanks": "Thanks."
}

string_nl.json

{    
"thanks": "Dankjewel."
}

Und dann verwenden Sie diese, um darauf zuzugreifen

S.of(context).thanks;

Es weiß, welche Sprache basierend auf der Standardsprache Ihres Telefons ausgewählt werden soll.

  • Vielleicht kann es verbessert werden, indem es auch Singleton gemacht wird

    – festsitzender Überlauf

    13. März 2019 um 7:37 Uhr

  • Ich schlage vor, jede Saite zu machen static const

    – Andre Sousa

    18. Mai 2019 um 22:11 Uhr

Benutzeravatar von CopsOnRoad
CopsOnRoad

Bildschirmfoto:

Ich werde die Antwort von Mantas ergänzen


Vollständiger Code (Null sicher):

Für diejenigen unter Ihnen, die kein Plug-in von Drittanbietern verwenden möchten, finden Sie hier, wie Sie dies tun können.

  1. Erstellen Sie einen Ordner strings In assets. Legen Sie Ihre Sprachdatei darin ab.

    assets
      strings
      - en.json // for english 
      - ru.json  // for russian
    
  2. Jetzt in en.jsonschreiben Sie beispielsweise Ihre Zeichenfolge.

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

    Ebenso im ru.json,

    {
      "text1": "Привет",
      "text2": "Мир"
    }
    
  3. Fügen Sie dies hinzu pubspec.yaml Datei (achte auf die Leerzeichen)

    flutter:
      uses-material-design: true
    
      assets:
        - assets/strings/en.json
        - assets/strings/ru.json
    
    flutter_localizations:
      sdk: flutter
    
  4. Jetzt können Sie diese Zeichenfolgen in Ihrer App verwenden. Hier ist der Beispielcode, der AppBar zeigt den übersetzten 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];
     }
    
     late 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;
     }
    

  • Beim Aufrufen der getText () -Methode erhalte ich einen Fehler, als wäre die Methode nicht definiert

    – Maaz Patel

    27. Mai 2020 um 10:41 Uhr

  • @MaazPatel Verwenden Sie den vollständigen Code, ohne Änderungen daran vorzunehmen?

    – CopsOnRoad

    27. Mai 2020 um 11:10 Uhr

  • Derzeit verfolge ich diesen gesamten Code. später werde ich meine Saiten hinzufügen

    – Maaz Patel

    27. Mai 2020 um 11:31 Uhr

  • @MaazPatel Ich bin mir nicht sicher, welchen Fehler du machst, aber dies ist der vollständige Code (von anderen getestet)

    – CopsOnRoad

    27. Mai 2020 um 11:34 Uhr

  • @Fatimaayaa Meinst du, du willst ein Argument aus der lokalen JSON-Datei übergeben, das geht leider nicht.

    – CopsOnRoad

    20. Juli 2021 um 15:04 Uhr

Sie können die in den Internationalisierungsabschnitten der Dokumentation dargestellten Methoden verwenden, um sowohl die zentralisierte Zeichenfolgenverwaltung als auch Übersetzungen zu steuern (falls Sie Übersetzungen benötigen).

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

Es könnte jedoch für eine einfache App mit nur wenigen Zeichenfolgen übertrieben sein.

Benutzeravatar von Cícero Moura
Cicero Moura

Ich würde diese Klassen in einzelne Dateien aufteilen, aber nur um meinen Ansatz für diese Frage zu erklären.

Ich habe eine Basisklasse, die meine String-Getter hat. Für jede Sprache, die ich unterstützen möchte, muss ich eine Klasse erstellen, die sich von dieser Klasse aus erstreckt und ihre Getter überschreibt. Wenn ich also eine Zeichenfolge erstelle, muss ich jede Implementierung dieser Basisklasse überschreiben. Es ist hilfreich zu vermeiden, dass Sie vergessen, eine gebietsschemaspezifische Zeichenfolge zu erstellen.

/// Interface strings
class Strings {

  String get hello;
}


/// English strings
class EnglishStrings extends Strings {
   
  @override
  String get hello => 'Hello';
}

/// Russian strings
class RussianStrings extends Strings {
  @override
  String get hello => 'Привет';
}

/// Portuguese strings
class PortugueseStrings extends Strings {
  @override
  String get hello => 'Olá';
}

Danach könnten Sie in einem globalen Bereich Ihrer Anwendung eine eindeutige Instanz des Gebietsschemas deklarieren, das Sie verwenden möchten (die Verwendung eines Singletons ist eine gute Option).

Ich zeige nur ein kurzes Beispiel für die Verwendung:

 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 PortugueseStrings();
      case 'ru':
        return RussianStrings();
      default:
        return EnglishStrings();
    }
  }

  static Resources of(BuildContext context){
    return Resources(context);
  }
}

Und schließlich die Verwendung in einem Widget:

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

Verwenden einer Erweiterung von BuildContext

Sie können BuildContext erweitern, um bestimmte Funktionen zu erstellen und Ihrer Anwendung mehr Leistung zu verleihen.
Diese ist ab erhältlich Pfeil 2.7. Mehr sehen.

app_context_extension.dart

extension AppContext on BuildContext {

  Resources get resources => Resources.from(this);

}

favoriten_seite.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);
  }
}

Verwenden von GlobalKey

Zusammen mit einer Erweiterung von BuildContext, wie oben gezeigt, können Sie auch GlobalKey verwenden. Grundsätzlich könnten Sie es verwenden, wenn Sie keine Kontextinstanz haben. Letzteres hat einen guten Vorteil. Sie können Strings überall in Ihrer Anwendung verwenden. Mit anderen Worten, wenn Sie beispielsweise ein Muster wie MVC verwenden und Zeichenfolgen in Ihren Controllern verwenden möchten, können Sie dies problemlos tun.

Sie können so etwas deklarieren:

Anwendung.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,
...

Und dann:

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);
  }
}

Ich hoffe es hilft!

Erstellen Sie zunächst einen neuen Strings-Ordner in assets und fügen Sie Ihre Sprach-JSON-Dateien hinzu.

assets
  strings
    - en.json
    - ar.json

Dies ist dein en.json Datei

{
  "title": "Flutter app"
}

Und das ist dein ar.json Datei

{
  "title": "تطبيق Flutter"
}

Dann ändern Sie Ihre pubspec.yaml Datei wie unten.

dependencies:
  # your other codes
  intl: ^0.17.0
  flutter_localizations:
    sdk: flutter


  # your other codes

flutter:
  uses-material-design: true

  assets:
    - assets/strings/en.json
    - assets/strings/ar.json

Danach erstellen AppLocalizations.dart Klasse

import 'dart:convert';

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

class AppLocalizations {
  static AppLocalizations of(BuildContext context) {
    return Localizations.of<AppLocalizations>(context, AppLocalizations);
  }

  String getText(String key) => language[key];
}

Map<String, dynamic> language;

class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
  const AppLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) => ['en', 'ar'].contains(locale.languageCode);

  @override
  Future<AppLocalizations> load(Locale locale) async {
    String string = await rootBundle.loadString("assets/strings/${locale.languageCode}.json");
    language = json.decode(string);
    return SynchronousFuture<AppLocalizations>(AppLocalizations());
  }

  @override
  bool shouldReload(AppLocalizationsDelegate old) => false;
}

Endlich in Ihrem main.dart Datei nehmen Sie die folgenden Änderungen vor

void main() async {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: AppLocalizations.of(context).getText("title"),
      locale: Locale("en"),
      localizationsDelegates: [const AppLocalizationsDelegate()],
      supportedLocales: [const Locale('en', ''), const Locale('ar', '')],  
      home: HomeScreen(),
    );
  }
}

  • Das ist eine schöne Lösung! Ich habe Ihre Lösung erweitert, um eine bessere Benutzerfreundlichkeit beim Codieren mit dieser Lösung zu bieten, siehe meine Antwort.

    – Marcel Hofgesang

    16. April 2022 um 14:03 Uhr


Benutzeravatar von jebran
jebran

  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

  • Das ist eine schöne Lösung! Ich habe Ihre Lösung erweitert, um eine bessere Benutzerfreundlichkeit beim Codieren mit dieser Lösung zu bieten, siehe meine Antwort.

    – Marcel Hofgesang

    16. April 2022 um 14:03 Uhr


Benutzeravatar von Irfandi D. Vendy
Irfandi D. Vendy

Ich verwende diese Methode, anstatt die Bibliothek von Drittanbietern zu verwenden. Grundsätzlich erstelle ich eine Klasse, die diese Werte enthält (String, Farben, Dimensionen usw.)

Ressourcen.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]);
  }
}

Rufen Sie dazu einfach die get-Methode auf

main.dart

import 'package:my_app/resources.dart';
...
    return Container(
      color: ResColor().get('colorPrimary')
    );
...

1443010cookie-checkString-XML-Datei in Flutter

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy