다국어 패키지 설정
다국어 패키지 추가
pubspec.yaml에 다국어 패키지를 추가 합니다. :
pubspec.yaml
#다국어 처리
flutter_localizations:
sdk: flutter
VS Code에서 pubspec.yaml 파일을 저장하면 자동으로 패키지를 다운로드 및 설치가 됩니다. 간혹 비정상적으로 패키지 설치가 안되었다면 수동으로 처리하면 됩니다.
수동 처리
$ flutter clean
$ flutter pub get
참고 블로
정리가 잘된 블로그가 있어 해당 블로그를 링크한다.
https://lovelyhongjja.tistory.com/7
JSON 언어 데이터 생성
assets/lang/ko.json
{
"title":"다국어 테스트_KO"
}
assets/lang/vi.json
{
"title":"다국어 테스트_VI"
}
Localization Delegate 생성
lib/util/localization/localization.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class Localization extends ChangeNotifier {
Localization(this.locale);
final Locale locale;
static Localization of(BuildContext context) {
return Localizations.of<Localization>(context, Localization);
}
Map<String, String> _localizedValues;
Future<void> load() async {
String jsonStringValues =
await rootBundle.loadString('assets/lang/${locale.languageCode}.json');
Map<String, dynamic> mappedJson = json.decode(jsonStringValues);
_localizedValues =
mappedJson.map((key, value) => MapEntry(key, value.toString()));
}
String translate(String key) {
return _localizedValues[key];
}
// static member to have simple access to the delegate from Material App
static const LocalizationsDelegate<Localization> delegate =
_LocalizationsDelegate();
}
class _LocalizationsDelegate extends LocalizationsDelegate<Localization> {
const _LocalizationsDelegate();
@override
bool isSupported(Locale locale) {
return ['ko', 'vi'].contains(locale.languageCode);
}
@override
Future<Localization> load(Locale locale) async {
Localization localization = new Localization(locale);
await localization.load();
return localization;
}
@override
bool shouldReload(LocalizationsDelegate<Localization> old) => false;
}
Localization Future 관련 생성
lib/util/localization/localization_constants.dart
import 'package:flutter/material.dart';
import 'package:localization_test/util/localization.dart';
import 'package:shared_preferences/shared_preferences.dart';
const String LAGUAGE_CODE = 'languageCode';
//languages code
//언어코드 참조
//https://api.flutter.dev/flutter/flutter_localizations/GlobalMaterialLocalizations-class.html
const String KOREAN = 'ko';
const String VIETNAMESE = 'vi';
Future<Locale> setLocale(String languageCode) async {
SharedPreferences _prefs = await SharedPreferences.getInstance();
await _prefs.setString(LAGUAGE_CODE, languageCode);
return _locale(languageCode);
}
Future<Locale> getLocale() async {
SharedPreferences _prefs = await SharedPreferences.getInstance();
String languageCode = _prefs.getString(LAGUAGE_CODE) ?? "ko";
return _locale(languageCode);
}
Locale _locale(String languageCode) {
switch (languageCode) {
case KOREAN:
return Locale(KOREAN, '');
case VIETNAMESE:
return Locale(VIETNAMESE, '');
default:
return Locale(KOREAN, '');
}
}
Future<String> getLanguageCode() async {
SharedPreferences _prefs = await SharedPreferences.getInstance();
return _prefs.getString(LAGUAGE_CODE) ?? "ko";
}
Future<String> getLanguageCodeWithCountryCode() async {
SharedPreferences _prefs = await SharedPreferences.getInstance();
String rtnCode = "ko-KR";
switch (_prefs.getString(LAGUAGE_CODE)) {
case 'ko':
rtnCode = "ko-KR";
break;
case 'vi':
rtnCode = "vi-VN";
break;
case 'zh':
rtnCode = "zh-CN";
break;
default:
rtnCode = "ko-KR";
break;
}
return rtnCode;
}
String getLanguageName(String languageCode) {
switch (languageCode) {
case KOREAN:
return 'Korean';
case VIETNAMESE:
return 'Vietnamese';
default:
return 'Korean';
}
}
String getTranslated(BuildContext context, String key) {
try {
String text = Localization.of(context).translate(key);
if (text != null) {
return text;
} else {
return key;
}
} catch (_) {
return key;
}
}
Main App 적용
lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:localization_test2/util/localization/language_constants.dart';
import 'package:localization_test2/util/localization/localization.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
//하위 화면에서 호출을 위한 모바일 언어 변경 static
static void setLocale(BuildContext context, Locale newLocale) {
_MyAppState state = context.findAncestorStateOfType<_MyAppState>();
state.setLocale(newLocale);
}
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
Locale _locale;
void setLocale(Locale locale) {
setState(() {
_locale = locale;
});
}
@override
void didChangeDependencies() {
//이전에 세팅된 언어 호출
getLocale().then((locale) {
setState(() {
this._locale = locale;
});
});
super.didChangeDependencies();
}
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// is not restarted.
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
localizationsDelegates: [
//Localization Delegate 선언
Localization.delegate, //앱에 생성한 Delegate
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
locale: _locale,
supportedLocales: [
//모바일 앱 지원 언어
const Locale('ko', ''), // English, no country code
const Locale('vi', ''), // Arabic, no country code
],
localeResolutionCallback: (locale, supportedLocales) {
//최초 모바일 실행 시 기본 모바일 설정 언어로 세팅
if (locale == null) {
debugPrint("*language locale is null!!!");
return supportedLocales.first;
} else {
debugPrint(
"languageCode : ${locale.languageCode}, countryCode:${locale.countryCode} ");
}
for (var supportedLocale in supportedLocales) {
if (supportedLocale.languageCode == locale.languageCode &&
(supportedLocale.countryCode ?? '') ==
(locale.countryCode ?? '')) {
return supportedLocale;
}
}
return supportedLocales.first;
},
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
다국어 적용
//Text 위젯에 다국어 적용
Text(getTranslated(context, 'title')), // 다국어 적용
//언어 변경 버튼
FlatButton(
child: Text('한국어', style: TextStyle(fontSize: 24)),
onPressed: () => changeLocale('ko'),
color: Colors.green,
textColor: Colors.white,
)
//언어 변경 처리 함수
void changeLocale(String lang) {
setLocale(lang);
MyApp.setLocale(context, Locale(lang, ''));
}
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;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(getTranslated(context, 'title')), // 다국어 적용
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
FlatButton(
child: Text('한국어', style: TextStyle(fontSize: 24)),
onPressed: () => changeLocale('ko'),
color: Colors.green,
textColor: Colors.white,
),
FlatButton(
child: Text('베트남어', style: TextStyle(fontSize: 24)),
onPressed: () => changeLocale('vi'),
color: Colors.green,
textColor: Colors.white,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
//언어 변경 처리 함수
void changeLocale(String lang) {
setLocale(lang);
MyApp.setLocale(context, Locale(lang, ''));
}
}
Last updated
Was this helpful?