【Flutter】動的に言語を変更する【flutter_localization/flutter_riverpod】

ネコニウム研究所

PCを利用したモノづくりに関連する情報や超個人的なナレッジを掲載するブログ

【Flutter】動的に言語を変更する【flutter_localization/flutter_riverpod】

2024-5-14 | ,

Flutterでflutter_localizationflutter_riverpodを使って動的に言語を変更したい!

概要

今回の記事では、Flutterでflutter_localizationflutter_riverpodを使って動的に言語を変更する手順を掲載する。

仕様書

環境

  • Android Studio Giraffe | 2023.2.1 Patch 2
  • Flutter 3.19.6

手順書

flutter_localizationのイントールと使い方については下記の記事を参照。

flutter_riverpodも使うので下記のコマンド等でイントールする。

flutter pub add http flutter_riverpod

DropdownButtonで言語を選択すると言語が切り替わる例。

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

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends ConsumerWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final locale = ref.watch(localeStateNotifierProvider);

    return MaterialApp(
        localizationsDelegates: const [
          AppLocalizations.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
        ],
        supportedLocales: const [
          Locale('en'),
          Locale('ja'),
        ],
        locale: Locale(locale),
        title: 'Flutter Test',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(
              seedColor: Colors.deepPurple, brightness: Brightness.light),
          useMaterial3: true,
        ),
        home: const Scaffold(body: DynamicLocalizationsSample1()));
  }
}

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final localeStateNotifierProvider =
    StateNotifierProvider<LocaleStateNotifier, String>((ref) {
  return LocaleStateNotifier();
});

class LocaleStateNotifier extends StateNotifier<String> {
  LocaleStateNotifier() : super("ja");

  void update(String locale) {
    state = locale;
  }
}

class DynamicLocalizationSample1 extends StatefulWidget {
  const DynamicLocalizationSample1({super.key});

  @override
  DynamicLocalizationState createState() => DynamicLocalizationState();
}

class DynamicLocalizationState extends State<DynamicLocalizationSample1> {
  String selectedLocale = 'ja';

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Center(
        child: Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
          Text(
            AppLocalizations.of(context)!.hello,
            style: const TextStyle(color: Color(0xFF000000)),
          ),
          Consumer(
            builder: (BuildContext context, WidgetRef ref, Widget? child) {
              return DropdownButton<String>(
                value: selectedLocale,
                onChanged: (String? value) {
                  setState(() {
                    selectedLocale = value ?? "ja";
                  });

                  ref
                      .read(localeStateNotifierProvider.notifier)
                      .update(selectedLocale);
                },
                items: const [
                  DropdownMenuItem(
                    value: 'ja',
                    child: Text('日本語'),
                  ),
                  DropdownMenuItem(
                    value: 'en',
                    child: Text('English'),
                  ),
                ],
              );
            },
          ),
        ]),
      ),
    );
  }
}

親のMaterialAppのプロパティを動的に変更するためにfullter_riverpodStateNotifierProviderを使ってる。

まとめ(感想文)

こちらもなかなか複雑な感じ。