easy_localization
easy and fast internationalizing your flutter apps, this package simplify the internationalizing process using json file
why easy_localization
- simplify and easy the internationalizing process in flutter.
- using json files .
- load translations from remote or backend.
- save app state.
- supported
plural
- supported
gender
- supported flutter extension.
changelog
[1.4.1]
- optimized and clean code
- fixed many issues
- added extension for strings
// after 1.4.1 text('title'.tr()), text('switch'.tr( gender: _gender ? "female" : "male")), text('counter'.plural(counter)),
[1.4.0]
- refactor code changed call
applocalizations.of(context).tr()
toapplocalizations.of(context).plural()
tr()
andplural()
// after 1.4.0 text( tr('switch', gender: _gender ? "female" : "male"), ),
// before 1.4.0 text( applocalizations.of(context).tr('switch', gender: _gender ? "female" : "male"), ),
- added flutter extension for text widget
// after 1.4.0 text('switch').tr( gender: _gender ? "female" : "male"), text('counter').plural(counter),
[1.3.5]
- merge
gender()
andtr()
.{ "switch":{ "male": "hi man ;)", "female": "hello girl :)" } }
text( applocalizations.of(context).tr('switch', gender: _gender ? "female" : "male"), ),
- use parameters
args
for gender.{ "switch":{ "male": "hi man ;) {}", "female": "hello girl :) {}" } }
text( applocalizations.of(context).tr('switch', args:["naama"] gender: _gender ? "female" : "male"), ),
[1.3.4]
- adeed gender [female,male]
gender()
.{ "switch":{ "male": "hi man ;)", "female": "hello girl :)" } }
text( applocalizations.of(context).gender('switch', _gender ? "female" : "male"), ),
[1.3.3+1]
- updated
plural()
thanks shushper .{ "text": { "day": { "zero":"{} дней", "one": "{} день", "two": "{} дня", "few": "{} дня", "many": "{} дней", "other": "{} дней" } } }
[1.3.3]
- removed
data.savedlocale
. - optimized and clean code
- fixed many issues
[1.3.2]
plural()
added property resolver for nested key translations{ "text": { "day": { "zero": "day", "one": "day", "other": "days" } } }
new text( applocalizations.of(context).plural("text.day", 2), ),
- fixed many issues
[1.3.1]
- add useonlylangcode flag
[1.3.0]
- load translations from remote or backend
- fixed many issues
[1.2.1]
- supported shared_preferences
- save selected localization
[1.2.0]
- added property resolver for nested key translations
- return translate key if the element or path not exist
{
"title": "hello",
"msg": "hello {} in the {} world ",
"clickme": "click me",
"profile": {
"reset_password": {
"title": "reset password",
"username": "username",
"password": "password"
}
},
"clicked": {
"zero": "you clicked {} times!",
"one": "you clicked {} time!",
"two":"you clicked {} times!",
"few":"you clicked {} times!",
"many":"you clicked {} times!",
"other": "you clicked {} times!"
}
}
new text(
applocalizations.of(context).tr('profile.reset_password.title'),
),
[1.0.4]
- added support country codes
[1.0.3]
- updated
tr()
function added multi argument
[1.0.2]
- added string pluralisation .
- added argument to
tr()
function.
getting started
configuration
add this to your package’s pubspec.yaml file:
dependencies:
# stable version install from https://pub.dev/packages
easy_localization: <last_version>
# dev version install from git repo
easy_localization:
git: https://github.com/aissat/easy_localization.git
load translations from local assets
you must create a folder in your project’s root: the path
. some examples:
/assets/”langs” , “i18n”, “locale” or anyname …
/resources/”langs” , “i18n”, “locale” or anyname …
inside this folder, must put the json files containing the translated keys :
path
/${languagecode}-${countrycode}.json
example:
- en.json to en-us.json
- ar.json to ar-dz.json
- zh.json to zh-cn.json
- zh.json to zh-tw.json
must declare the subtree in your pubspec.yaml as assets:
flutter:
assets:
- {`path`/{languagecode}-{countrycode}.json}
the next step :
import 'package:example/my_flutter_app_icons.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:easy_localization/easy_localization.dart';
void main() => runapp(easylocalization(child: myapp()));
class myapp extends statelesswidget {
@override
widget build(buildcontext context) {
var data = easylocalizationprovider.of(context).data;
return easylocalizationprovider(
data: data,
child: materialapp(
title: 'flutter demo',
localizationsdelegates: [
globalmateriallocalizations.delegate,
globalwidgetslocalizations.delegate,
//app-specific localization
easylocalizationdelegate(
locale: data.locale,
path: 'resources/langs',
//useonlylangcode: true,
// loadpath: 'https://raw.githubusercontent.com/aissat/easy_localization/master/example/resources/langs'
),
],
supportedlocales: [locale('en', 'us'), locale('ar', 'dz')],
locale: data.locale,
theme: themedata(
primaryswatch: colors.blue,
),
home: myhomepage(title: 'easy localization'),
),
);
}
}
class myhomepage extends statefulwidget {
myhomepage({key key, this.title}) : super(key: key);
final string title;
@override
_myhomepagestate createstate() => _myhomepagestate();
}
class _myhomepagestate extends state<myhomepage> {
int counter = 0;
bool _gender = true;
incrementcounter() {
setstate(() {
counter++;
});
}
switchgender(bool val) {
setstate(() {
_gender = val;
});
}
@override
widget build(buildcontext context) {
var data = easylocalizationprovider.of(context).data;
return easylocalizationprovider(
data: data,
child: scaffold(
appbar: appbar(
title: text(tr("title")),
actions: <widget>[
flatbutton(
child: text("english"),
color: localizations.localeof(context).languagecode == "en"
? colors.lightblueaccent
: colors.blue,
onpressed: () {
this.setstate(() {
data.changelocale(locale("en", "us"));
print(localizations.localeof(context).languagecode);
});
},
),
flatbutton(
child: text("عربي"),
color: localizations.localeof(context).languagecode == "ar"
? colors.lightblueaccent
: colors.blue,
onpressed: () {
this.setstate(() {
data.changelocale(locale("ar", "dz"));
print(localizations.localeof(context).languagecode);
});
},
)
],
),
body: center(
child: column(
mainaxisalignment: mainaxisalignment.center,
children: <widget>[
spacer(
flex: 1,
),
text(
'switch.with_arg',
style: textstyle(
color: colors.grey.shade600,
fontsize: 19,
fontweight: fontweight.bold),
).tr(args: ["aissat"], gender: _gender ? "female" : "male"),
text(
tr('switch', gender: _gender ? "female" : "male"),
style: textstyle(
color: colors.grey.shade600,
fontsize: 15,
fontweight: fontweight.bold),
),
row(
mainaxisalignment: mainaxisalignment.center,
children: <widget>[
icon(myflutterapp.male_1),
switch(value: _gender, onchanged: switchgender),
icon(myflutterapp.female_1),
],
),
spacer(
flex: 1,
),
text(tr('msg', args: ['aissat', 'flutter'])),
// text(plural('clicked', counter)),
text('clicked').plural(counter),
flatbutton(
onpressed: () {
incrementcounter();
},
child: text('clickme').tr(),
),
sizedbox(height: 15,),
text(
plural('amount', counter,
format: numberformat.currency(
locale: localizations.localeof(context).tostring(),
symbol: "€")),
style: textstyle(
color: colors.grey.shade900,
fontsize: 18,
fontweight: fontweight.bold)
),
sizedbox(height: 20,),
text('profile.reset_password.title').tr(),
spacer(
flex: 2,
),
],
),
),
floatingactionbutton: floatingactionbutton(
onpressed: incrementcounter,
child: text('+1'),
),
),
);
}
}
load translations from backend
you need to have backend endpoint (loadpath
) where resources get loaded from and your endpoint must containing the translated keys.
example:
string loadpath = 'https://raw.githubusercontent.com/aissat/easy_localization/master/example/resources/langs'
‘${
loadpath
}/${languagecode}-${countrycode}.json’
- ‘https://raw.githubusercontent.com/aissat/easy_localization/master/example/resources/langs/en-us.json’
- ‘https://raw.githubusercontent.com/aissat/easy_localization/master/example/resources/langs/ar-dz.json’
the next step :
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:easy_localization/easy_localization.dart';
void main() => runapp(easylocalization(child: myapp()));
class myapp extends statelesswidget {
@override
widget build(buildcontext context) {
var data = easylocalizationprovider.of(context).data;
return easylocalizationprovider(
data: data,
child: materialapp(
title: 'flutter demo',
localizationsdelegates: [
globalmateriallocalizations.delegate,
globalwidgetslocalizations.delegate,
//app-specific localization
easylocalizationdelegate(
locale: data.locale,
loadpath: 'https://raw.githubusercontent.com/aissat/easy_localization/master/example/resources/langs'),
],
supportedlocales: [locale('en', 'us'), locale('ar', 'dz')],
locale: data.locale,
theme: themedata(
primaryswatch: colors.blue,
),
home: myhomepage(title: 'easy localization'),
),
);
}
}
class myhomepage extends statefulwidget {
myhomepage({key key, this.title}) : super(key: key);
final string title;
@override
_myhomepagestate createstate() => _myhomepagestate();
}
class _myhomepagestate extends state<myhomepage> {
int counter = 0;
incrementcounter() {
setstate(() {
counter++;
});
}
@override
widget build(buildcontext context) {
var data = easylocalizationprovider.of(context).data;
return easylocalizationprovider(
data: data,
child: scaffold(
appbar: appbar(
title: text(tr('title')),
actions: <widget>[
flatbutton(
child: text("english"),
color: localizations.localeof(context).languagecode == "en"
? colors.lightblueaccent
: colors.blue,
onpressed: () {
this.setstate(() {
data.changelocale(locale("en","us"));
print(localizations.localeof(context).languagecode);
});
},
),
flatbutton(
child: text("عربي"),
color: localizations.localeof(context).languagecode == "ar"
? colors.lightblueaccent
: colors.blue,
onpressed: () {
this.setstate(() {
data.changelocale(locale("ar","dz"));
print(localizations.localeof(context).languagecode);
});
},
)
],
),
body: center(
child: new column(
mainaxisalignment: mainaxisalignment.center,
children: <widget>[
new text(applocalizations.of(context)
.tr('msg', args: ['aissat', 'flutter'])),
new text(plural('clicked', counter)),
new flatbutton(
onpressed: () async {
incrementcounter();
},
child: new text(tr('clickme')),
),
new text(
tr('profile.reset_password.title'),
),
],
),
),
floatingactionbutton: floatingactionbutton(
onpressed: incrementcounter,
child: text('+1'),
),
),
);
}
}
screenshots
arbic rtl | english ltr |
---|---|
Comments are closed.