Как быстро загрузить переводы на Flutter - PullRequest
0 голосов
/ 01 октября 2019

Моя команда и я работаем над мобильной игрой, которая позволяет пользователю установить свой основной язык. При первой загрузке появляется красный экран, показывающий, что некоторые переводы не были загружены, и через некоторое время исчезает.

enter image description here

Мы следовали инструкциям Флаттера и можем получитьпереводы, но при изменении языка в параметрах и при запуске, мы получаем этот экран.

Наш главный:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import ...

void main() {
  SystemChrome.setPreferredOrientations(...).then((_){runApp(MyApp());});
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Trade on Tubes',
        theme: ThemeData(...),
        localizationsDelegates: [
          const TranslationsDelegate(),
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
        ],
        supportedLocales: [
          const Locale('en', ''),
          const Locale('fr', ''),
          const Locale('es', ''),
        ],
        home: RootPage(auth: Auth(), lateralMenuPage: 0,)
    );
  }
}

Вот наша RootPage:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import ...

class RootPage extends StatefulWidget {
  RootPage({this.auth, this.lateralMenuPage});
  final AuthImpl auth;
  final int lateralMenuPage;

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

enum AuthStatus {...}

class _RootPageState extends State<RootPage> {
  AuthStatus authStatus = AuthStatus.NOT_DETERMINED;
  User currentUser;
  String locale;
  String devise;
  bool theme;

  @override
  void initState() {
    super.initState();
    _loadPreferences();
    widget.auth.getCurrentUserID().then((user) {
      setState(() {
        if (user == null) {
          authStatus = AuthStatus.NOT_SIGNED_IN;
        }
        else {
          widget.auth.getUserInfos(user).then(...);
        }
      });
    });
  }

  void _signedInAndRegistered() {
    setState(() {
      widget.auth.getUserAvatar(currentUser.userID).then((ava){...});
      authStatus = AuthStatus.SIGNED_IN_AND_REGISTERED;
    });
  }

  void _signedInAndNotRegistered() {
    widget.auth.getCurrentUserID().then((user){
      setState(() {
        widget.auth.getUserInfos(user).then(...);
      });
    });
  }

  void _signedOut() {
    setState(() {
      authStatus = AuthStatus.NOT_SIGNED_IN;
    });
  }

  Future<void> _loadPreferences() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      theme = (prefs.getBool('switchButton') ?? true);
      devise = (prefs.getString('deviseButton') ?? "EUR");
      locale = (prefs.getString('_radioValue1') ?? 'fr');
      Translations.load(Locale.fromSubtags(languageCode: locale));
    });
    await Themes.load(theme);
    await Devise.load(devise);
  }

  @override
  Widget build(BuildContext context) {
    ...
    switch (authStatus) {
      case AuthStatus.NOT_DETERMINED:
        return Container(
          height: GV.globalH,
          width: GV.globalW,
          color: Colors.white,
          child: Center(
              child: CircularProgressIndicator()
          ),
        );
      case AuthStatus.NOT_SIGNED_IN:
        return LoginPage(
          auth: widget.auth,
          onSignedIn: _signedInAndNotRegistered,
        );
      case AuthStatus.SIGNED_IN_AND_REGISTERED:
        return currentUser.friends.isEmpty
            ? Tutorial(currentUser, widget.auth, 0)
            :RadialMenu(
          currentUser: currentUser,
          auth: widget.auth,
          page: widget.lateralMenuPage,);
      case AuthStatus.SIGNED_IN_AND_NOT_REGISTERED:
        return RegistrationPage(
          auth: widget.auth,
          onSignedOut: _signedOut,
          onRegistered: _signedInAndRegistered,
        );
    }
  }
}

И нашLoginPage:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:trade_on_tube/translation/translations.dart';
import ...

class LoginPage extends StatefulWidget {
  LoginPage({this.auth, this.onSignedIn});
  final AuthImpl auth;
  final VoidCallback onSignedIn;

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

enum FormMode{SIGNIN, SIGNUP}

class _LoginPageState extends State<LoginPage> {
  final formKey = GlobalKey<FormState>();
  bool _isLoading;
  bool _alpha = false;
  bool _obscureText = true;
  String _email;
  String _password;
  FormMode _formMode = FormMode.SIGNIN;
  bool _checkBox;

  @override
  void initState(){
    _checkBox = false;
    _isLoading = false;
    super.initState();
  }

  Widget _showCircularProgress(){...}

  bool validateAndSave() {...}

  void validateAndSubmit()async{
    setState(() {...});
    if(validateAndSave()) {
      String userId = '';
      try {
        if(_formMode == FormMode.SIGNIN) {
          userId = await widget.auth.signIn(_email, _password);
          _alpha = true;
        } else {
          if(_checkBox) {
            userId = await widget.auth.signUp(_email, _password);
            _showDialog2();
            setState(() {
              _formMode = FormMode.SIGNIN;
              _isLoading = false;
            });
          }else {
            _alpha = false;
            showDialog(
              context: context,
              builder: (BuildContext context) {
                return AlertDialog(
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(25.0)),
                  title: Text(Translations.of(context).text('cgu')),
                  content: Text(Translations.of(context).text('read_cgu')),
                  actions: <Widget>[
                    RaisedButton(
                      onPressed: () => Navigator.of(context).pop(),
                      padding: EdgeInsets.symmetric(
                          vertical: 10.0, horizontal: 12.0),
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(25.0)),
                      color: Theme
                          .of(context)
                          .primaryColor,
                      child: Text(Translations.of(context).text('the_what'),
                        style: TextStyle(
                            fontSize: 15.0, color: Colors.white70),),
                    )
                  ],
                );
              },
            );
          }
        }
        setState(() {
          _isLoading = false;
        });
        if(userId.length > 0 && userId != null && _alpha)
          widget.onSignedIn();
      } catch (e) {
        setState(() {
          print(e);
          _isLoading = false;
          if(userId == null) {
            showDialog(
              context: context,
              builder: (BuildContext context){
                return AlertDialog(
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(25.0)),
                  title: Text(Translations.of(context).text('email')),
                  content: Text(Translations.of(context).text('email_not_verified')),
                  actions: <Widget>[
                    RaisedButton(
                      onPressed: () => Navigator.of(context).pop(),
                      padding: EdgeInsets.symmetric(
                          vertical: 10.0, horizontal: 12.0),
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(25.0)),
                      color: Theme
                          .of(context)
                          .primaryColor,
                      child: Text(Translations.of(context).text('my_bad'),
                        style: TextStyle(fontSize: 15.0, color: Colors.white70),),
                    )
                  ],
                );
              },
            );
          }else
            _showDialog();
        });
      }
    }
  }

  void validateAndSubmitGoogleSignIn() async {...}

  void _signUp() {...}

  void _signIn() {...}

  void _showDialog(){
    showDialog(
        context: context,
        builder: (BuildContext context){
          return AlertDialog(
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(25.0)),
            title: Text(Translations.of(context).text('problem')),
            content: Text(Translations.of(context).text('problem_2'),),
            actions: <Widget>[
              RaisedButton(
                onPressed: (){
                  Navigator.of(context).pop();
                },
                padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(25.0)),
                color: Theme.of(context).primaryColor,
                child: Text(Translations.of(context).text('ok'),
                  style: TextStyle(fontSize: 15.0, color: Colors.white),),
              ),
            ],
          );
        }
    );
  }

  void _showDialog2(){
    String title = Translations.of(context).text('welcome');
    String message = Translations.of(context).text('welcome_message');
    String button = Translations.of(context).text('go');

    showDialog(
      context: context,
      builder: (BuildContext context){
        return AlertDialog(
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(25.0)),
          title: Text(title),
          content: Text(message),
          actions: <Widget>[
            RaisedButton(
              onPressed: () => Navigator.of(context).pop(),
              padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(25.0)),
              color: Theme.of(context).primaryColor,
              child: Text(button, style: TextStyle(fontSize: 15.0, color: Colors.white70),),
            )
          ],
        );
      },
    );
  }

  Widget _logo(String path, double radius, String tag) {...}

  Widget _checkboxCGU(){
    if(_formMode == FormMode.SIGNUP) {
      return Row(
        children: <Widget>[
          InkWell(
            onTap: () {
              setState(() {
                _checkBox = !_checkBox;
              });
            },
            child: Container(
              child: Padding(
                padding: const EdgeInsets.all(10.0),
                child: _checkBox
                  ? Icon(Icons.check_circle, size: 22.0, color: Colors.blue,)
                  : Icon(FontAwesomeIcons.circle, size: 22.0, color: Colors.blue,),
              ),
            ),
          ),
          GestureDetector(
            onTap: () => launch("http://www.barracudapps.com/applis/trade_on_tubes.php"),
            child: Text(Translations.of(context).text('cgu'),
              style: TextStyle(fontSize: 13.0,
                color: Colors.blue,
                decoration: TextDecoration.underline,
              ),
            ),
          )
        ],
      );
    } else{
      return SizedBox(height: 2.0);
    }
  }

  Widget _emailInput() {
    return TextFormField(
      style: TextStyle(color: Themes.themes.text),
      keyboardType: TextInputType.emailAddress,
      autofocus: false,
      decoration: InputDecoration(
        enabledBorder: UnderlineInputBorder(
          borderSide: BorderSide(color: Themes.themes.text),
        ),
        hintText: Translations.of(context).text('email'),
        hintStyle: TextStyle(color: Themes.themes.text),
        icon: Icon(
          Icons.mail,
          color: Themes.themes.text,
        ),
      ),
      validator: (value) =>
      value.isEmpty ? Translations.of(context).text('email_empty') : null,
      onSaved: (value) => _email = value,
    );
  }

  Widget _passwordInput() {
    return Row(
      mainAxisSize: MainAxisSize.max,
      children: <Widget>[
        Container(
          width: MediaQuery
              .of(context)
              .size
              .width / 2 - 90,
          child: TextFormField(
            style: TextStyle(color: Themes.themes.text),
            obscureText: _obscureText,
            autofocus: false,
            decoration: InputDecoration(
              enabledBorder: UnderlineInputBorder(
                borderSide: BorderSide(color: Themes.themes.text),
              ),
              hintText: Translations.of(context).text('password'),
              hintStyle: TextStyle(color: Themes.themes.text),
              icon: Icon(
                Icons.lock,
                color: Themes.themes.text,
              ),
            ),
            validator: (value) =>
            value.isEmpty ? Translations.of(context)
                .text('password_empty') : null,
            onSaved: (value) => _password = value,
          ),
        ),
        FlatButton(
          onPressed: () =>
              setState(() {
                _obscureText = !_obscureText;
              }),
          child: Icon(
            _obscureText ? FontAwesomeIcons.solidEye : FontAwesomeIcons
                .solidEyeSlash, color: Themes.themes.text,),
        ),
      ],
    );
  }

  Widget _forgotPassword() {
    return GestureDetector(
      onTap: () => Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => ForgotPasswordPage(auth: widget.auth)),
      ),
      child: Text(
        Translations.of(context).text('forgot_password'),
        style: TextStyle(fontSize: 13.0, color: Colors.blue, decoration: TextDecoration.underline),
      ),
    );
  }

  Widget _label() {
    return FlatButton(
      child: _formMode == FormMode.SIGNIN
          ? Text(Translations.of(context).text('click_create_account'),
          style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.w600, color: Themes.themes.text))
          : Text(Translations.of(context).text('click_login'),
          style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.w600, color: Themes.themes.text)),
      onPressed: _formMode == FormMode.SIGNIN
          ? _signUp
          : _signIn,
    );
  }

  Widget _submitButton() {
    if (_formMode == FormMode.SIGNIN) {
      return Padding(
        padding: EdgeInsets.symmetric(vertical: 0.0),
        child: Material(
          borderRadius: BorderRadius.circular(30.0),
          shadowColor: Colors.redAccent.shade100,
          elevation: 1.0,
          child: MaterialButton(
            minWidth: 290.0,
            height: 35.0,
            color: GV.firstColor,
            child: Text(Translations.of(context).text('login'),
              style: TextStyle(fontSize: 20.0, color: Colors.white),),
            onPressed: validateAndSubmit,
          ),
        ),
      );
    } else {
      return Padding(
        padding: EdgeInsets.symmetric(vertical: 0.0),
        child: Material(
          borderRadius: BorderRadius.circular(30.0),
          shadowColor: Colors.redAccent.shade100,
          elevation: 1.0,
          child: MaterialButton(
            minWidth: 290.0,
            height: 35.0,
            color: GV.firstColor,
            child: Text(Translations.of(context).text('create_account'),
              style: TextStyle(fontSize: 20.0, color: Colors.white),),
            onPressed: validateAndSubmit,
          ),
        ),
      );
    }
  }

  Widget _googleSignIn(){
    return Padding(
      padding: EdgeInsets.symmetric(vertical: 8.0),
      child: RaisedButton(
        color: Colors.transparent,
        elevation: 0.0,
        child:_logo("assets/Autres/google.png", 20, 'google'),
        onPressed: validateAndSubmitGoogleSignIn,
      ),
    );
  }

  Widget _bodyOne(){
    return Container(
      width: GV.globalW,
      height: GV.globalH,
      decoration: BoxDecoration(color: GV.firstColor),
      child: Themes.themes.background_inscription,
    );
  }

  Widget _bodyTwo(){
    return Container(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          SizedBox(width: GV.globalW/4,),
          Flexible(
            child: Form(
              key: formKey,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  _emailInput(),
                  _passwordInput(),
                  SizedBox(height: GV.globalH/35,),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: <Widget>[
                      _checkboxCGU(),
                      _forgotPassword(),
                    ],
                  ),
                  SizedBox(height: GV.globalH/35,),
                  _submitButton(),
                  _label(),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      SizedBox(
                        width: 130.0,
                        height: 1.0,
                        child: const DecoratedBox(
                          decoration: const BoxDecoration(
                            color: Colors.white,
                          ),
                        ),
                      ),
                      Text(Translations.of(context).text('or'),
                        style: TextStyle(fontSize: 15.0, fontWeight: FontWeight.w300, color: Themes.themes.text),),
                      SizedBox(
                        width: 130.0,
                        height: 1.0,
                        child: const DecoratedBox(
                          decoration: const BoxDecoration(
                            color: Colors.white,
                          ),
                        ),
                      ),
                    ],
                  ),
                  _googleSignIn(),
                ],
              ),
            ),
          ),
          SizedBox(width: GV.globalW/4,),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    SystemChrome.setEnabledSystemUIOverlays([]);
    return Scaffold(
      resizeToAvoidBottomPadding: false,
      body: Stack(
        children: <Widget>[
          _bodyOne(),
          _bodyTwo(),
          _showCircularProgress(),
        ],
      ),
    );
  }
}
...