localizely / flutter-intl-vscode

This VS Code extension generates boilerplate code for localization of Flutter apps with official Dart Intl library
MIT License
87 stars 1 forks source link

MaterialApp goes to black for a few milliseconds when adding "S.delegate" #31

Closed bogdanorzea closed 4 years ago

bogdanorzea commented 4 years ago

Hello, I noticed that there is a UI problem when using this extension and a Bloc to switch to another MaterialApp. I tried to recreate this problem using a simple sample:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'generated/l10n.dart';

main() {
  runApp(CustomBloc());
}

class CustomBloc extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider<ChangeMaterialAppBloc>(
      create: (context) => ChangeMaterialAppBloc(),
      child: Builder(
        builder: (context) => BlocBuilder<ChangeMaterialAppBloc, bool>(
          builder: (context, state) {
            if (state) {
              return MaterialApp(
                key: Key("TRUE"),
                localizationsDelegates: [
                  GlobalMaterialLocalizations.delegate,
                  GlobalWidgetsLocalizations.delegate,
                  S.delegate,
                ],
                supportedLocales: S.delegate.supportedLocales,
                home: Scaffold(
                  appBar: AppBar(title: Text("TRUE")),
                  body: Center(
                    child: RaisedButton(
                      onPressed: () => BlocProvider.of<ChangeMaterialAppBloc>(context).add(SetState(value: false)),
                      child: Text("SWITCH TO FALSE"),
                    ),
                  ),
                ),
              );
            } else {
              return MaterialApp(
                key: Key("FALSE"),
                localizationsDelegates: [
                  GlobalMaterialLocalizations.delegate,
                  GlobalWidgetsLocalizations.delegate,
                  S.delegate,
                ],
                supportedLocales: S.delegate.supportedLocales,
                home: Scaffold(
                  appBar: AppBar(title: Text("FALSE")),
                  body: Center(
                    child: RaisedButton(
                      onPressed: () => BlocProvider.of<ChangeMaterialAppBloc>(context).add(SetState(value: true)),
                      child: Text("SWITCH TO TRUE"),
                    ),
                  ),
                ),
              );
            }
          },
        ),
      ),
    );
  }
}

class ChangeMaterialAppBloc extends Bloc<SetState, bool> {
  @override
  bool get initialState => true;

  @override
  Stream<bool> mapEventToState(SetState event) async* {
    if (event is SetState) {
      yield event.value;
    }
  }
}

class SetState {
  const SetState({this.value});

  final bool value;
}

In my example, once I comment out "S.delegate", the problem goes away. I'm using version 1.8.0 of localizely.flutter-intl.

https://gfycat.com/latehiddencattle

aleksakrstic commented 4 years ago

Hi @bogdanorzea Hmm, this seems caused by code generated by https://github.com/dart-lang/intl_translation that this plugin relies on.

By the way, is there a reason you reinstantiate MaterialApp on every click, and not defining MaterialApp as a root widget? Not sure how good that practice is in general, and having MaterialApp as a root should probably fix this issue.

bogdanorzea commented 4 years ago

Hi @aleksakrstic and thanks for your answer. I was adding a few bloc providers and bloc listeners above the MaterialApp so that I can react to things like login/logout or account creation.

Based on your feedback, I refactored the layout so that I have Providers > MaterialApp > Builders > Screens. By doing this, I can change the language and locale programmatically and I don't see any weird flickering anymore.

Thanks for your feedback and help!