states_rebuilder
states_rebuilder copied to clipboard
Localization with ARB files and the App Title
So, I have been working with the ARB translation tools, moving to ARB from an earlier localization project, and ran across a minor issue.
I want to point out that injecting the Title
does not allow for the MaterialApp.title
to update dynamically, only during App rebuilding. So, the only reason to address this is simply a matter of making the ARB the master document, and the title to be translated just like everything else.
In the Skeleton template for Flutter, it uses ARB out of the gate, and uses the ARB files for their MaterialApp.title
using the onGenerateTitle
process instead of setting the parameter directly.
In an attempt to duplicate this method, I ran into the issue that I hadn't had in earlier versions of States Rebuilder, where I was able to set the title without issue using i18rn.of(context)
So, here is the code as it is expected to operate:
class MyApp extends TopStatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
locale: i18nRM.locale,
localeResolutionCallback: i18nRM.localeResolutionCallback,
localizationsDelegates: i18nRM.localizationsDelegates,
onGenerateTitle: (context) => i18nRM.of(context).appTitle,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(), // Notice const,
);
}
}
and here is the working code:
class MyApp extends TopStatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return TopAppWidget(
builder: (context) => MaterialApp(
locale: i18nRM.locale,
localeResolutionCallback: i18nRM.localeResolutionCallback,
localizationsDelegates: i18nRM.localizationsDelegates,
onGenerateTitle: (context) => i18nRM.of(context).appTitle,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(), // Notice const,
),
);
}
}
In earlier versions of States Rebuilder (Version 5) the TopAppWidget()
was the parent of the MaterialApp()
widget, and a TopStatelessWidget
was not extended by the MyApp
.
I am not sure of the side effects this code would create in 6, notice that MyApp
still extends TopStatelessWidget
. I am assuming that nesting `MaterialApp' inside another 'MaterialApp' lower in the tree might work as well, but I haven't tried that.
I do know that injection isn't in place by the time the Title
is being generated, which is generating a hard exception unless the MaterialApp
is one step lower in the tree.
@GIfatahTH, can you note your thoughts on this?
Hi @cidothia
If I understand your case well, you want the onGenerateTitle
method to be called when you switch between languages.
I used a simple example to check the case, and it works for me.
Please correct me if I am wrong!
import 'package:flutter/material.dart';
import 'package:states_rebuilder/states_rebuilder.dart';
class En {
final String appTitle = 'english';
}
class Fr extends En {
final String appTitle = 'french';
}
final i18nRM = RM.injectI18N({
'en'.locale(): () => En(),
'fr'.locale(): () => Fr(),
});
void main(List<String> args) {
runApp(_MyApp());
}
class _MyApp extends TopStatelessWidget {
const _MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
locale: i18nRM.locale,
localeResolutionCallback: i18nRM.localeResolutionCallback,
localizationsDelegates: i18nRM.localizationsDelegates,
onGenerateTitle: (context) {
// See console log to check that this callback is invoked with the right
// language
print(i18nRM.of(context).appTitle);
return i18nRM.of(context).appTitle;
},
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const _MyHomePage(), // Notice const,
);
}
}
class _MyHomePage extends StatelessWidget {
const _MyHomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(i18nRM.of(context).appTitle)),
floatingActionButton: FloatingActionButton(
onPressed: () => i18nRM.locale == 'fr'.locale()
? i18nRM.locale = 'en'.locale()
: i18nRM.locale = 'fr'.locale(),
),
);
}
}