• 다국어 지원(Localization)
    모바일 개발/Flutter 2025. 11. 16. 10:18
    반응형

    플러터 프로젝트에 localization을 세팅하는 방법에 대해 정리한다.

     

       코드 적용

    1. pubspec.yaml 파일 수정

        1) flutter_localizations 추가

        dependencies:
          flutter:
            sdk: flutter
          flutter_localizations: # 추가
            sdk: flutter # 추가

        2) generate 추가

        # The following section is specific to Flutter packages.
        flutter:
          uses-material-design: true
          generate: true # 추가

     

    2. 언어 리소스 파일 생성

    - {프로젝트_루트}/lib/l10n 폴더 안에, 파일 이름은 app_{언어코드}.arb 형태로 생성해준다.

     

    리소스 파일을 작성할 때 주의해야 할 점은 다음과 같다.

    - json 형식 사용: 짝을 잘 맞춰 작성한다.

    - 동일한 리소스 사용: app_en.arb에 appTitle이 있다면 app_ko.arb에도 appTitle 값이 존재해야 한다.

    - dart convention 적용: 각 리소스 이름은 camelCase로 작성해야 하며, 대문자/숫자/언더스코어로 시작할 수 없다.

    - 영어, 한국어, 일본어 버전이 필요할 경우: lib/l10n/app_en.arb, lib/l10n/app_ko.arb, lib/l10n/app_ja.arb 생성

     

    e.g. lib/l10n/app_en.arb

        {
          "@@locale": "en",
          "appTitle": "My Flutter App",
          "confirm": "Confirm",
          "cancel": "Cancel",
          "permissionMessage": "This app requires permission to access your camera."
        }

    e.g. lib/l10n/app_ko.arb

        {
          "@@locale": "ko",
          "appTitle": "나의 플러터 앱",
          "confirm": "확인",
          "cancel": "취소",
          "permissionMessage": "카메라 접근 권한이 필요합니다."
        }

    e.g. lib/l10n/app_ja.arb

    {
      "@@locale": "ja",
      "appTitle": "私のアプリ",
      "confirm": "確認",
      "cancel": "キャンセル",
      "permissionMessage": "このアプリはカメラの権限が必要です。"
    }

     

    3. 프로젝트 빌드

    프로젝트를 빌드한다.

     

    이때 에러로 인해 프로젝트가 빌드되지 않는 경우, 혹은 vscode가 바로바로 변경을 감지하지 못 하는 경우,

    터미널 창에서 아래 명령어를 직접 실행해 app_localization.dart 파일을 수동으로 생성해준다.

    (2번 리소스 파일에 문제가 있을 경우 수동 생성에 실패하니 주의할 것.)

    flutter gen-l10n

    성공했을 경우 .dart_tool/flutter_gen/gen_l10n/ 폴더 안에 app_localizations.dart 파일이 생성된다.

     

    위 명령어가 다음과 같은 에러로 실패할 경우,

    1) pubspec.yaml에 generate: true를 추가했는지
    2) 이 명령어를 실행하고 있는 작업 디렉토리가 프로젝트 루트 디렉토리인지 한 번 더 확인한다.

    Attempted to generate localizations code without having the flutter: generate flag turned on.
    Check pubspec.yaml and ensure that flutter: generate: true has been added and rebuild the project. Otherwise, the localizations source code will not be importable.

     

    ** Flutter 3.32버전부터 app_localizations.dart 파일이 디폴트 경로(.dart_tool/...)에 생성되지 않도록 변경되었다. **

    해당 파일은 프로젝트 루트 디렉토리에 l10n.yaml 파일을 만들어서 경로를 따로 지정하지 않은 이상 lib/l10n/ 경로에 생성되었을 것이다.

    flutter_gen/gen_l10n/app_localizations.dart 대신 프로젝트_이름/l10n/app_localizations.dart를 임포트해서 사용하면 된다.

    참고: https://docs.flutter.dev/release/breaking-changes/flutter-generate-i10n-source

     

    4. MaterialApp이 포함된 dart 파일 상단에 필요한 패키지 추가

      import 'package:flutter_localizations/flutter_localizations.dart';
      import 'package:flutter_gen/gen_l10n/app_localizations.dart';

     

    5. main.dart MaterialApp 부분 수정

      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          // ===== 추가
          localizationsDelegates: const [
            AppLocalizations.delegate,
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
            GlobalCupertinoLocalizations.delegate,
          ],
          // ===== 추가
          supportedLocales: const [
            Locale('ko'),
            Locale('en'),
            Locale('ja'),
          ],
          // ===== 추가
          localeListResolutionCallback: (locales, supportedLocales) {
            for (var supported in supportedLocales) {
              if (supported.languageCode == locales?.first.languageCode) {
                return supported;
              }
            }
            return supportedLocales.first;
          },
          home: const WebviewScreen(),
        );
      }

    supportedLocalesLocale('ko')를 먼저 넣어 한국어를 fallback 언어로 세팅하였다.

     

     

       사용 방법

    1. dart 파일 상단에 import 추가

    import 'package:flutter_gen/gen_l10n/app_localizations.dart';


    2. 필요한 곳에서 다음과 같이 사용

        Text(AppLocalizations.of(context)!.appTitle)
        final localizations = AppLocalizations.of(context)!;
    
        return Scaffold(
          appBar: AppBar(
            title: Text(localizations.appTitle),
          ),
          body: Center(
            child: Text(
              localizations.permissionMessage,
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ),
        );

    이때 앞에 const를 붙일 수 없다. (컴파일 시점 아닌 런타임 시점에 값 결정)

     

     

       앱 이름 적용

    안드로이드

    1. android/app/src/main/res/values 폴더에 strings.xml 생성

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="app_name">My App</string>
    </resources>


    2. android/app/src/main/res 폴더에

    values-ko, values-ja 폴더를 필요한 언어에 맞춰 생성하고 (values-언어코드 형식)

    그 안에 strings.xml 각각 생성

     

    e.g. values-ko/strings.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="app_name">나의 앱</string>
    </resources>

    각 언어 파일에 맞는 언어로 작성한다.


    3. AndroidManifest.xml 파일 내 application > android:label을 "@string/app_name"으로 수정

    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
        <application
            android:label="@string/app_name"
    ...

     

     

    iOS

    1. Runner.xcworkspace 눌러서 xcode 실행


    2. 왼쪽 내비게이터에서 최상단 Runner 선택하고

    Project>Runner, Info>Localizations에서 + 눌러 언어 추가 (e.g. Korean, Japanese)

    이때 팝업 뜨는 건 디폴트로 두고 Finish 선택


    3. 왼쪽 내비게이터에서 Runner(ios/Runner) 폴더 우클릭 후,

    New File From Template > Strings File(Legacy) 선택


    4. Save As:에 InfoPlist 입력


    5. 내비게이터에서 생성된 InfoPlist를 선택하고,

    우측 속성 창의 Localization 부분에서 English, Korean, Japanese 등 필요한 언어 모두 선택

    => 자동으로 InfoPlist (English), InfoPlist (Korean) 등등 생성됨


    6. 5에서 생성된 각 파일에 CFBundleDisplayName 값 추가
    e.g. InfoPlist (Korean)

    CFBundleDisplayName = "나의 앱";

      

    7. Info.plist에서 Bundle display name 값 비워두기

     


    적용이 제대로 안 될 경우

    1. clean 실행 후 다시 빌드

    flutter clean
    flutter pub get
    flutter run


    2. 앱 삭제 후 재설치

     

    반응형

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

    Firebase Messaging  (0) 2025.11.21
    앱 아이콘 세팅  (0) 2025.11.21
    패키지 코틀린 버전 맞추기  (0) 2025.11.16
    플러터 apk, ipa 파일 생성  (1) 2025.08.06
    inappwebview로 html 파일 열기  (1) 2025.08.06

    댓글

ABOUT ME

공부한 것을 기록하기 위해 블로그를 개설했습니다.

VISIT

/