다국어 패키지 설정

다국어 패키지 추가

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?