Skip to content

Commit

Permalink
feat: Adding basic i18n. #4
Browse files Browse the repository at this point in the history
Person can't make switches yet.
  • Loading branch information
LuchoTurtle committed May 10, 2023
1 parent 6665924 commit 0cd3899
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 9 deletions.
4 changes: 4 additions & 0 deletions assets/i18n/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"title": "This is the main page",
"description": "Check the todo item below to open the menu above to check more pages."
}
5 changes: 5 additions & 0 deletions assets/i18n/pt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"title": "Esta é a página inicial.",
"description": "Clica no item abaixo para abrir o menu acima para ver mais páginas."
}

56 changes: 56 additions & 0 deletions lib/app_localization.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import 'dart:convert';

import 'package:app/settings.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

/// Utils class for app localization with delegate
class AppLocalization {
late final Locale _locale;

AppLocalization(this._locale);

static AppLocalization of(BuildContext context) {
return Localizations.of<AppLocalization>(context, AppLocalization)!;
}

late Map<String, String> _localizedValues;

// This function will load requested language `.json` file and will assign it to the `_localizedValues` map
Future loadLanguage() async {
String jsonStringValues = await rootBundle.loadString("assets/i18n/${_locale.languageCode}.json");

Map<String, dynamic> mappedValues = json.decode(jsonStringValues);

_localizedValues = mappedValues.map((key, value) =>
MapEntry(key, value.toString())); // converting `dynamic` value to `String`, because `_localizedValues` is of type Map<String,String>
}

String? getTranslatedValue(String key) {
return _localizedValues[key];
}

static const LocalizationsDelegate<AppLocalization> delegate = _AppLocalizationDelegate();
}

/// Private overriden delegate class
class _AppLocalizationDelegate extends LocalizationsDelegate<AppLocalization> {
const _AppLocalizationDelegate();

// It will check if the user's locale is supported by our App or not
@override
bool isSupported(Locale locale) {
return ["en", "pt"].contains(locale.languageCode);
}

// It will load the equivalent json file requested by the user
@override
Future<AppLocalization> load(Locale locale) async {
AppLocalization appLocalization = AppLocalization(locale);
await appLocalization.loadLanguage();
return appLocalization;
}

@override
bool shouldReload(_AppLocalizationDelegate old) => false;
}
34 changes: 27 additions & 7 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

import 'app_localization.dart';
import 'menu.dart';

const iconKey = Key("menu_icon");
Expand All @@ -23,6 +25,24 @@ class App extends StatelessWidget {
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
supportedLocales: const [
Locale('en', 'US'),
Locale('pt', 'PT'),
],
localeResolutionCallback: (deviceLocale, supportedLocales) {
for (var locale in supportedLocales) {
if (locale.languageCode == deviceLocale!.languageCode && locale.countryCode == deviceLocale.countryCode) {
return deviceLocale;
}
}
return supportedLocales.first;
},
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
AppLocalization.delegate
],
home: const HomePage());
}
}
Expand Down Expand Up @@ -82,16 +102,16 @@ class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
"This is the main page",
style: TextStyle(fontSize: 30),
Text(
AppLocalization.of(context).getTranslatedValue("title").toString(),
style: const TextStyle(fontSize: 30),
),
const Padding(
padding: EdgeInsets.all(16),
Padding(
padding: const EdgeInsets.all(16),
child: Text(
"Check the todo item below to open the menu above to check more pages.",
AppLocalization.of(context).getTranslatedValue("description").toString(),
textAlign: TextAlign.center,
style: TextStyle(fontSize: 15, color: Colors.black87),
style: const TextStyle(fontSize: 15, color: Colors.black87),
),
),
ListTile(
Expand Down
13 changes: 13 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.1"
flutter_localizations:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
Expand All @@ -192,6 +197,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.1"
intl:
dependency: transitive
description:
name: intl
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
url: "https://pub.dev"
source: hosted
version: "0.17.0"
js:
dependency: transitive
description:
Expand Down
6 changes: 4 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ environment:
dependencies:
flutter:
sdk: flutter

flutter_localizations:
sdk: flutter

# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
Expand Down Expand Up @@ -64,7 +65,8 @@ flutter:
# To add assets to your application, add an assets section, like this:
assets:
- assets/images/
- assets/
- assets/i18n/
- assets/menu_items.json

# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
Expand Down

0 comments on commit 0cd3899

Please sign in to comment.