การใช้ Internationalization (i18n) ใน Flutter
ในโลกที่เชื่อมต่อถึงกันมากขึ้น การสร้างแอปพลิเคชันที่รองรับหลายภาษาเป็นสิ่งสำคัญอย่างยิ่ง Internationalization (i18n) คือกระบวนการออกแบบและพัฒนาแอปพลิเคชันให้สามารถปรับตัวเข้ากับภาษาและวัฒนธรรมที่แตกต่างกันได้ โดยไม่ต้องแก้ไขโค้ดหลัก ส่วน Localization (l10n) คือกระบวนการปรับแต่งแอปพลิเคชันสำหรับภาษาและวัฒนธรรมเฉพาะ ในบทความนี้ เราจะมาเรียนรู้วิธีการใช้ i18n ใน Flutter เพื่อทำให้แอปของคุณรองรับหลายภาษาได้อย่างง่ายดาย
ทำไมต้อง Internationalization (i18n)?
i18n มีประโยชน์มากมายสำหรับแอปพลิเคชันของคุณ:
- เข้าถึงผู้ใช้ได้มากขึ้น: รองรับภาษาที่หลากหลาย ทำให้แอปของคุณเข้าถึงผู้ใช้จำนวนมากขึ้นทั่วโลก
- ประสบการณ์ผู้ใช้ที่ดีขึ้น: ผู้ใช้จะรู้สึกสบายใจและใช้งานแอปของคุณได้ง่ายขึ้น หากแอปแสดงผลเป็นภาษาที่พวกเขาเข้าใจ
- ความน่าเชื่อถือ: แอปที่รองรับหลายภาษาแสดงถึงความใส่ใจและความเป็นมืออาชีพ
- ความได้เปรียบทางการแข่งขัน: การรองรับหลายภาษาอาจเป็นปัจจัยสำคัญที่ทำให้แอปของคุณโดดเด่นกว่าคู่แข่ง
การเตรียมความพร้อมสำหรับ i18n ใน Flutter
Flutter มีเครื่องมือและไลบรารีที่ช่วยให้การทำ i18n เป็นเรื่องง่าย หนึ่งในไลบรารีที่สำคัญที่สุดคือ flutter_localizations ซึ่งเป็นส่วนหนึ่งของ Flutter SDK
1. เพิ่ม Dependency:
เริ่มต้นด้วยการเพิ่ม dependency flutter_localizations และ intl ลงในไฟล์ pubspec.yaml ของคุณ:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
จากนั้นรัน flutter pub get เพื่อดาวน์โหลดและติดตั้ง dependencies เหล่านี้
2. กำหนด Supported Locales:
ในไฟล์ main.dart ของคุณ กำหนด supportedLocales ใน MaterialApp widget เพื่อระบุภาษาที่แอปของคุณรองรับ:
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter i18n Demo',
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'), // English, United States
const Locale('th', 'TH'), // Thai, Thailand
],
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter i18n Demo'),
),
body: Center(
child: Text('Hello World'), // This will be localized later
),
);
}
}
ในตัวอย่างนี้ เรากำหนดให้แอปของเราสนับสนุนภาษาอังกฤษ (US) และภาษาไทย (TH)
3. สร้างไฟล์ Localization:
สร้างไฟล์ Dart สำหรับแต่ละภาษาที่คุณต้องการรองรับ ไฟล์เหล่านี้จะเก็บข้อความที่แปลแล้ว ตัวอย่างเช่น สำหรับภาษาอังกฤษ (US) เราจะสร้างไฟล์ lib/l10n/app_en.arb:
{
"helloWorld": "Hello World",
"@helloWorld": {
"description": "The conventional newborn greeting"
}
}
และสำหรับภาษาไทย (TH) เราจะสร้างไฟล์ lib/l10n/app_th.arb:
{
"helloWorld": "สวัสดีชาวโลก",
"@helloWorld": {
"description": "คำทักทายสากล"
}
}
ไฟล์ .arb (Application Resource Bundle) เป็นรูปแบบ JSON ที่ใช้กันทั่วไปสำหรับการจัดเก็บข้อความที่แปลแล้ว @helloWorld คือ metadata ที่ให้คำอธิบายเพิ่มเติมเกี่ยวกับข้อความ (optional แต่แนะนำให้ใช้)
การใช้งาน Localization ใน Widget
1. สร้าง Class สำหรับ Localization:
สร้าง class ที่จัดการการเข้าถึงข้อความที่แปลแล้ว ตัวอย่างเช่น AppLocalizations:
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class AppLocalizationsHelper {
static AppLocalizations? of(BuildContext context) {
return AppLocalizations.of(context);
}
}
2. Generate Localization Class:
Flutter มีเครื่องมือที่ช่วย generate code จากไฟล์ .arb ได้อัตโนมัติ โดยใช้ package flutter_gen เพิ่ม dependency นี้ลงใน dev_dependencies ใน pubspec.yaml:
dev_dependencies:
flutter_test:
sdk: flutter
flutter_gen_runner: ^5.3.2
build_runner: ^2.4.6
flutter_gen:
output: lib/gen_l10n/ # Optional (default: lib/gen_l10n/)
line_length: 80 # Optional (default: 80)
จากนั้นรันคำสั่ง:
flutter pub get
flutter gen-l10n
คำสั่งนี้จะสร้างไฟล์ lib/gen_l10n/app_localizations.dart (หรือตามที่กำหนดใน output) ซึ่งมี class AppLocalizations ที่เราสามารถใช้เข้าถึงข้อความที่แปลแล้วได้
3. แก้ไข MaterialApp:
แก้ไข MaterialApp เพื่อใช้ AppLocalizations.delegate:
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter i18n Demo',
localizationsDelegates: [
AppLocalizations.delegate, // Add this line
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'), // English, United States
const Locale('th', 'TH'), // Thai, Thailand
],
home: MyHomePage(),
);
}
}
4. ใช้งานใน Widget:
ตอนนี้เราสามารถเข้าถึงข้อความที่แปลแล้วใน widget ของเราได้ โดยใช้ AppLocalizations.of(context):
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter i18n Demo'),
),
body: Center(
child: Text(AppLocalizations.of(context)!.helloWorld), // Use the localized text
),
);
}
}
เมื่อคุณรันแอปพลิเคชัน ระบบจะแสดงข้อความ "Hello World" หรือ "สวัสดีชาวโลก" ขึ้นอยู่กับภาษาที่ตั้งค่าไว้ในอุปกรณ์ของคุณ
การจัดการ Locale
Flutter ให้วิธีในการจัดการ locale ของแอปพลิเคชันอย่างง่ายดาย
1. BuildContext.locale:
คุณสามารถเข้าถึง locale ปัจจุบันของแอปพลิเคชันได้โดยใช้ BuildContext.locale ใน widget ของคุณ:
Locale currentLocale = Localizations.localeOf(context);
print('Current Locale: ${currentLocale.languageCode}');
2. การเปลี่ยน Locale:
คุณสามารถเปลี่ยน locale ของแอปพลิเคชันได้โดยใช้ SystemNavigator.selectMultiLocale (สำหรับ Android) หรือโดยการสร้าง StatefulWidget ที่จัดการ Locale และ rebuild MaterialApp:
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Locale _locale = const Locale('en', 'US'); // Default locale
void _changeLocale(Locale newLocale) {
setState(() {
_locale = newLocale;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter i18n Demo',
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'),
const Locale('th', 'TH'),
],
locale: _locale, // Set the current locale
home: MyHomePage(changeLocale: _changeLocale),
);
}
}
class MyHomePage extends StatelessWidget {
final Function(Locale) changeLocale;
const MyHomePage({Key? key, required this.changeLocale}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter i18n Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(AppLocalizations.of(context)!.helloWorld),
SizedBox(height: 20),
ElevatedButton(
onPressed: () => changeLocale(const Locale('th', 'TH')),
child: Text('Change to Thai'),
),
ElevatedButton(
onPressed: () => changeLocale(const Locale('en', 'US')),
child: Text('Change to English'),
),
],
),
),
);
}
}
ในตัวอย่างนี้ เราสร้างปุ่มสองปุ่มที่อนุญาตให้ผู้ใช้เปลี่ยนภาษาของแอปพลิเคชันได้
ข้อควรระวังและแนวปฏิบัติที่ดี
- ใช้
intlpackage:intlpackage มีเครื่องมือสำหรับการจัดการรูปแบบวันที่ เวลา ตัวเลข และสกุลเงินตาม locale - วางแผนโครงสร้างไฟล์: สร้างโครงสร้างไฟล์ที่ชัดเจนสำหรับไฟล์ localization ของคุณ เพื่อให้ง่ายต่อการจัดการและบำรุงรักษา
- ใช้เครื่องมือแปลภาษา: พิจารณาใช้เครื่องมือแปลภาษาอัตโนมัติหรือบริการแปลภาษาจากผู้เชี่ยวชาญ เพื่อให้ได้การแปลที่ถูกต้องและเป็นธรรมชาติ
- ทดสอบอย่างละเอียด: ทดสอบแอปของคุณในภาษาต่างๆ เพื่อให้แน่ใจว่าทุกอย่างทำงานได้อย่างถูกต้อง
สรุป
Internationalization (i18n) เป็นส่วนสำคัญของการสร้างแอปพลิเคชันที่ประสบความสำเร็จในระดับโลก Flutter มีเครื่องมือและไลบรารีที่ช่วยให้การทำ i18n เป็นเรื่องง่าย ด้วยการทำตามขั้นตอนที่เราได้กล่าวมาในบทความนี้ คุณจะสามารถสร้างแอปพลิเคชันที่รองรับหลายภาษาได้อย่างง่ายดาย และเข้าถึงผู้ใช้จำนวนมากขึ้นทั่วโลก ในบทความถัดไป เราจะพูดถึง Localization (l10n) ในรายละเอียดมากขึ้น