1

I've learned How to use i18n via StatelessWidget for my flutter practice, but still not work via StatefulWidget.

I can simply replace the following code

title: new Text(S.of(context).title)

with a const String, for example:

title: const Text("A Test Title");

So I think every thing else should be okay. The only problem is i18n not work.

Could some body help me, "How to use i18n via StatefulWidget on flutter ?"

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'generated/i18n.dart';

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

class MyApp extends StatefulWidget {
  MyApp({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  BuildContext c;

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    var tiles = new List<Widget>();

    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text(S.of(context).title), // Here is the problem
        ),
        body: new Stack(
          children: <Widget>[
            new Container(),
            new ListView(
              children: tiles,
            )
          ],
        ),
      ),
      localizationsDelegates: [S.delegate],
      supportedLocales: S.delegate.supportedLocales,
      localeResolutionCallback: S.delegate.resolution(
          fallback: new Locale("en", "")
      ),
    );
  }
}

1 Answers1

5

The context you're using doesn't have a MaterialApp as a parent. Instead, it has a MaterialApp as a child.

The problem is, S instance you're trying to fetch using S.of(context) is stored inside MaterialApp. Hence the error.

What you can instead do is use a different context where that context has MaterialApp in its parents.

The easiest way to achieves this is by wrapping a part of your app into a Builder.

Something like :

return MaterialApp(
  home: Builder(
    builder: (context) {
      const title = S.of(context).title; // works now because the context used has a MaterialApp inside its parents
      return Scaffold(...);
    }
  )
)
Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
  • Thanks for your helpful comments. This morning I tried the same way with yours, and finally works. – ChingKun Yu Jul 03 '18 at 02:13
  • This solution is still available in 2020. Unfortunately most of tutorials written/video are based only on Stateless widgets which have different type of context beside Statefull Widgets – ricristian Jan 11 '20 at 01:52
  • This also worked for me, Except that mine is a StatelessWidget – Tyler Mutai Mar 14 '20 at 11:35