본문 바로가기
개발/Flutter

[Flutter] 앱 번역하기 (Flutter Localization)

by 감토끼 2018. 12. 11.



Flutter 앱을 번역하는 법을 정리하겠습니다.

(참고한 곳)



1. 패키지 설치

pubspec.yaml 


dependencies:
flutter:
sdk: flutter
flutter_localizations: # 추가
sdk: flutter # 추가
intl: ^0.15.7 # 추가
intl_translation: ^0.17.2 # 추가


flutter packages get



2. ios 설정

ios/Runner/Info.plist


...


 <key>CFBundleDevelopmentRegion</key>

 <string>en</string>

 

<!-- 다음 부분을 추가 -->

 <key>CFBundleLocalizations</key>

 <array>

 <string>en</string>

 <string>ko</string>

 </array>

 

...



3. 번역 클래스 생성

lib/src/loc/loc.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:intl/date_symbol_data_local.dart';

// 이 부분은 잠시 후 주석을 제거할 예정!
//import '../../l10n/messages_all.dart';

class Loc {
static Future<Loc> load(Locale locale) async {
final String localeName = locale.countryCode == null || locale.countryCode.isEmpty
? locale.languageCode
: locale.toString();

final String canonicalLocaleName = Intl.canonicalizedLocale(localeName);

// 이 부분은 잠시 후 주석을 제거할 예정!
// await initializeMessages(canonicalLocaleName);
await initializeDateFormatting(canonicalLocaleName);

Intl.defaultLocale = canonicalLocaleName;

return Loc();
}

static Loc of(BuildContext context) => Localizations.of(context, Loc);


// 번역 키와 기본 언어 번역
String get appName => Intl.message('Mobile POS', name: 'appName');
String get ok => Intl.message('Ok', name: 'ok');
String get yes => Intl.message('Yes', name: 'yes');
String get no => Intl.message('No', name: 'no');

}


lib/src/loc_delegate.dart

import 'dart:async';

import 'package:flutter/material.dart';

import 'loc.dart';

class LocDelegate extends LocalizationsDelegate<Loc> {
const LocDelegate();

@override
bool isSupported(Locale locale) => ['en', 'ko'].contains(locale.languageCode);

@override
Future<Loc> load(Locale locale) => Loc.load(locale);

@override
bool shouldReload(LocalizationsDelegate<Loc> old) => false;
}



4. arb 파일 생성

arb 파일을 생성할 폴더를 먼저 생성합니다.

mkdir lib/l10n


loc.dart 파일을 추출하여 arb 파일을 생성하는 명령어 실행

flutter pub pub run intl_translation:extract_to_arb --output-dir=lib/l10n lib/src/loc/loc.dart



위 명령어를 실행하면 다음과 같이 arb 파일이 만들어집니다.



내용은 다음과 같습니다. 이 intl_messages.arb 파일은 기본 언어(예제의 경우 영어) 번역 시 사용됩니다.


lib/l10n/intl_messages.arb

{
"@@last_modified": "2018-12-11T20:12:39.288301",
"appName": "Mobile POS",
"@appName": {
"type": "text",
"placeholders": {}
},
"ok": "Ok",
"@ok": {
"type": "text",
"placeholders": {}
},
"yes": "Yes",
"@yes": {
"type": "text",
"placeholders": {}
},
"no": "No",
"@no": {
"type": "text",
"placeholders": {}
}
}



5. 한국어용 arb 파일 생성

기본 언어 파일을 복사하여 한국어 파일을 생성합니다.

cp lib/l10n/intl_messages.arb lib/l10n/intl_messages_ko.arb



intl_messages_ko.arb 파일을 열어서 편집합니다.

맨 윗줄의 "@@locale": "ko" 부분도 반드시 입력하세요.


lib/l10n/intl_messages_ko.arb

{
"@@locale": "ko",
"@@last_modified": "2018-12-11T20:12:39.288301",
"appName": "모바일 포스",
"@appName": {
"type": "text",
"placeholders": {}
},
"ok": "확인",
"@ok": {
"type": "text",
"placeholders": {}
},
"yes": "",
"@yes": {
"type": "text",
"placeholders": {}
},
"no": "아니오",
"@no": {
"type": "text",
"placeholders": {}
}
}



6. messages_XXX.dart 파일 생성

마지막으로 arb 파일을 추출하여 messages_XXX.dart 생성하는 명령어를 입력합니다.

flutter pub pub run intl_translation:generate_from_arb lib/src/loc/loc.dart lib/l10n/*.arb  --output-dir=lib/l10n



최종적인 번역 파일 모습입니다.



7. loc.dart 주석 풀기 

다시 lib/src/loc/loc.dart 로 돌아가서 주석 되있던 부분
(이 부분은 잠시 후 주석을 제거할 예정! 이라고 써있던 2곳)의 주석을 제거 합니다.

lib/src/loc/loc.dart


import '../../l10n/messages_all.dart'; // 주석 제거

class Loc {
static Future<Loc> load(Locale locale) async {
final String localeName = locale.countryCode == null || locale.countryCode.isEmpty
? locale.languageCode
: locale.toString();

final String canonicalLocaleName = Intl.canonicalizedLocale(localeName);

await initializeMessages(canonicalLocaleName); // 주석 제거
await initializeDateFormatting(canonicalLocaleName);


...


8. 앱 번역 설정

main.dart

import 'package:flutter_localizations/flutter_localizations.dart';


import 'src/loc/loc.dart'; import 'src/loc/loc_delegate.dart';




void main() => runApp(MyApp());


class MyApp extends StatelessWidget {

@override
Widget build(BuildContext context) {

return MaterialApp(
title: 'Mobile Pos',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: MainHome(),



// 다음 부분 추가

localizationsDelegates: [

const LocDelegate(),

GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
// 디바이스 설정과 매칭되는 언어가 없을 경우 첫번째 언어로 번역한다.
const Locale('en', 'US'),
const Locale('ko')
]
,





);
}

}



9. 번역 값 사용하기

모든 사전 작업이 끝났습니다. 번역 값은 'Loc.of(context).XXX' 형태로 사용하면 됩니다.


main.dart

...


class MyApp extends StatelessWidget {

@override
Widget build(BuildContext context) {

return MaterialApp(


// title 부분을 아래와 같이 변경
//title: 'Mobile Pos',
onGenerateTitle: (BuildContext context) => Loc.of(context).appName,

...



10. 번역 값 추가하기

번역값을 추가하고 싶은 경우 다음의 작업을 반복하면 됩니다.


1. loc.dart 에 키 값과 번역 값을 추가


2. arb 파일 생성

flutter pub pub run intl_translation:extract_to_arb --output-dir=lib/l10n lib/src/loc/loc.dart


3. intl_messages.arb 파일을 열어 새롭게 추가된 부분을 복사하고 intl_messages_ko.arb 에 붙여넣기 한 후 한글로 번역하기


4. messages_XXX.dart 생성

flutter pub pub run intl_translation:generate_from_arb lib/src/loc/loc.dart lib/l10n/*.arb  --output-dir=lib/l10n


'개발 > Flutter' 카테고리의 다른 글

[Flutter] Hot Reload by command line  (0) 2018.12.11
[Flutter] Flutter 1.0 릴리즈  (0) 2018.12.11
[Flutter] Flutter앱 개발의 매력  (8) 2018.12.08