Đa Ngôn Ngữ Cho Ứng Dụng Flutter Với LanguageHelper

·

4 min read

PHẦN 1: CÁC BƯỚC THIẾT LẬP VÀ SỬ DỤNG CƠ BẢN

GIỚI THIỆU

Có nhiều cách để có thể sử dụng được nhiều ngôn ngữ (hay còn gọi là localization) cho ứng dụng Flutter. Ở bài viết này, mình sẽ giới thiệu thư viện language_helper và cách sử dụng của nó để có thể tạo ứng dụng đa ngôn ngữ một cách đơn giản và hiệu quả nhất.

TÍNH NĂNG

  • Dễ dàng kiểm soát và thay đổi ngôn ngữ trong ứng dụng. Tự động áp dụng ngôn ngữ hiện tại của máy cho ứng dụng.

  • Có thể kiểm soát bản dịch với LanguageConditions (như dịch số nhiều trong tiếng Anh).

  • Sử dụng generator để tách chuỗi cần thiết để tiện cho việc dịch (không cần sử dụng build_runner nên chạy rất nhanh).

  • Có thể sử dụng Language Helper Translator trên Chat GPT-4 để hỗ trợ dễ hơn cho việc dịch.

CÀI ĐẶT

Chỉ có bước này là bắt buộc trong quá trình phát triển ứng dụng, những bước còn lại có thể thực hiện sau khi ứng dụng đã sẵn sàng cho việc phát hành.

  • Thêm language_helper vào project:

      flutter pub add language_helper
    
  • Thêm khởi tạo ngôn ngữ vào project:

      main() async {
        WidgetsFlutterBinding.ensureInitialized();
        await LanguageHelper.instance.initial(data: []);
        runApp(const MyApp());
      }
    
  • Thêm .tr, .trP hay .trF vào những chuỗi cần dịch:

    • Cơ bản:

        Text('Chữ cần dịch'.tr)
      
    • Dịch có điều kiện:

        Text('Xin chào @{name}'.trP({'name': name}))
      
    • Số nhiều:

        final data = {
            'We have @{number} dollar': LanguageConditions(
                param: 'number',
                conditions: {
                    '0': 'We have zero dollar',
                    '1': 'We have one dollar',
                    '_': 'We have @{number} dollars'
                },
            ),
        }
      
        Text('We have @{number} dollar'.trP({'number': number}))
      

GENERATOR

Generate:

dart run language_helper:generate

Đường dẫn sau khi chạy:

.lib
|--- resources
|    |--- language_helper
|    |    |--- language_data.dart
|    |    |--- languages
|    |    |    |--- _generated.dart   ; This file will be overwritten when re-generating

DỊCH VÀ HIỆU CHỈNH

Tạo thêm tệp với ngôn ngữ tương ứng như en.dart, vi.dart,... ở trong thư mục languages.

Mở Language Helper Translator trên Chat-GPT 4, sao chép nội dung trong tệp _generated.dart, dán vào với theo mẫu sau và tiến hành dịch:

Đây là bản dịch của ứng dụng [Tên ứng dụng và mục đích cơ bản của ứng dụng]. Dịch sang [Ngôn ngữ đích]:

```dart
const analysisLanguageData = <String, dynamic>{
  'Xin chào @{name}': 'Xin chào @{name}',
  'Chúng ta có @{number} đô-la': 'Chúng ta có @{number} đô-la',
};
```

Sao chép kết quả và dán vào tệp ngôn ngữ tương ứng. Chẳng hạn như tệp en.dart:

const en = <String, dynamic>{
  'Xin chào @{name}': 'Xin chào @{name}',
  'Chúng ta có @{number} đô-la': 'We have @{number} dollar',
};

Hiệu chỉnh lại kết quả cần thiết như số nhiều, bạn có thể hiệu chỉnh trực tiếp ở biến en hoặc tạo biến mới như enOverride như sau:

final enOverride = <String, dynamic>{
  'Chúng ta có @{number} đô-la': LanguageCondition(
    param: 'number',
    conditions: {
      '0': 'We have zero dollar',
      '1': 'We have one dollar',
      '_': 'We have @{number} dollars',
    }
  ),
};

Thêm ngôn ngữ vừa dịch vào tệp language_data.dart:

LanguageData data = {
  LanguageCodes.vi: analysisLanguageData,
  LanguageCodes.en: en,
};

LanguageData dataOverrides = {
  LanguageCodes.en: enOverride,
};

Cập nhật lại trong project:

main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await LanguageHelper.instance.initial(
      data: [LanguageDataProvider.data(data)]
      dataOverrides: [LanguageDataProvider.data(dataOverrides)],   
  );
  runApp(const MyApp());
}

CẬP NHẬT WIDGET KHI NGÔN NGỮ THAY ĐỔI

Sử dụng LanguageBuilder hoặc Tr cho những Widget cần thay đổi khi ứng dụng thay đổi ngôn ngữ. Chỉ có LanguageBuilder cần thiết được cập nhật nên bạn có không cần quan tâm nếu sử dụng LanguageBuilder ở nhiều nơi dẫn đến dư thừa.

MaterialApp:

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return LanguageBuilder(
      builder: (context) {
        return MaterialApp(
          localizationsDelegates: languageHelper.delegates,
          supportedLocales: languageHelper.locales,
          locale: languageHelper.locale,
          home: const HomePage(),
        );
      }
    );
  }
}

Widget:

LanguageBuilder(
    builder: (context) {
        return Scaffold(
          body: Column(
            children: [
              Text('Xin chào @{name}'.tr),
              Text('Chúng ta có @{number} đô-la'.tr),
            ],
          ),
        );
    },
),

Sử dụng Tr (Phiên bản thu gọn của LanguageBuilder):

Tr((_) => Text('Xin chào @{name}'.tr)),

KIỂM SOÁT NGÔN NGỮ

Thay đổi ngôn ngữ:

languageHelper.change(LanguageCodes.vi);

Thêm bản dịch mới:

languageHelper.addData(LanguageDataProvider.data(newLanguageData));
languageHelper.addDataOverrides(LanguageDataProvider.data(newLanguageDataOverrides));

KẾT LUẬN

Ở phần mở đầu, chúng ta đã hoàn thành việc cài đặt và cách sử dụng căn bản cho language_helper. Ở phần tiếp theo, chúng ta sẽ tìm hiểu cách thiết lập để có thể sử dụng được cho ứng dụng phức tạp hơn với JSON.