質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

解決済

1回答

1156閲覧

Flutterで別ファイルからMaterialAppのlocaleを操作したい

RyuHo

総合スコア42

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2022/12/17 03:39

前提

(例)
Flutterでアプリ開発をしています。main.dartを別のファイルに2分割して、MaterialApp()が記述されていないほうのファイルからMaterialAppのlocaleを動的に変更したいです。

MaterialApp()がある方(main.dart)

dart

1//..... 2import 'settings.dart'; 3 4void main() { 5 runApp(NewApp()); 6} 7 8String lang = "en"; 9class NewApp extends StatelessWidget { 10 final title = "Tokage"; 11 12 13 Widget build(BuildContext context) { 14 return MaterialApp( 15 locale: Locale(lang), 16 localizationsDelegates: [ 17 AppLocalizations.delegate, 18 GlobalMaterialLocalizations.delegate, 19 GlobalWidgetsLocalizations.delegate, 20 GlobalCupertinoLocalizations.delegate, 21 ], 22 supportedLocales: [ 23 const Locale('ja', ''), 24 const Locale('en', ''), 25 ], 26 title: title, 27 //..... 28 home: new TokageHome()); 29 } 30} 31

分割したもう一つの方(settings.dart)

dart

1//..... 2import 'main.dart'; 3 4//prefはmain.dartでgetInstance()されています 5late SharedPreferences pref; 6 7class EnvironmentSettings extends StatefulWidget { 8 EnvironmentSettings() : super(); 9 10 _EnvironmentState createState() => new _EnvironmentState(); 11} 12 13class _EnvironmentState extends State<EnvironmentSettings> { 14 15 void initState() { 16 super.initState(); 17 } 18 19 20 Widget build(BuildContext context) { 21 return Scaffold( 22 appBar: AppBar( 23 title: Text(AppLocalizations.of(context)!.settings), 24 actions: <Widget>[], 25 ), 26 body: ListView( 27 children: <Widget>[ 28 Row( 29 mainAxisAlignment: MainAxisAlignment.spaceBetween, 30 children: [ 31 Container( 32 padding: EdgeInsets.fromLTRB(100, 30, 0, 0), 33 child: Row(children: [ 34 Text( 35 AppLocalizations.of(context)!.language, 36 style: 37 TextStyle(fontSize: 23, fontWeight: FontWeight.w300), 38 ) 39 ]), 40 ), 41 Container( 42 padding: EdgeInsets.fromLTRB(0, 30, 100, 0), 43 child: DropdownButton<String>( 44 value: pref.getString("language"), 45 items: [ 46 DropdownMenuItem( 47 child: Text(AppLocalizations.of(context)!.english), 48 value: "en", 49 ), 50 DropdownMenuItem( 51 child: Text(AppLocalizations.of(context)!.japanese), 52 value: "ja", 53 ) 54 ], 55 onChanged: (value) { 56 changeSetting("language", value.toString()); 57 }, 58 ), 59 width: 200, 60 ) 61 ], 62 ) 63 ], 64 )); 65 } 66 67 68 void changeSetting(String key, String value) { 69 pref.setString(key, value); 70 if(key == "ja"){ 71 //ここにlocaleを変数valueの値に変更するコードを書きたいです 72 } 73 setState(() {}); 74 } 75} 76

バージョン

Flutter 3.3.8
Dart 2.18.4
を使っています。

初心者ですのでおかしい部分が多々あるかもしれませんが、教えていただけると大変うれしいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

下記のように
ウィジェットツリーの上方で言語設定用の状態変数(localeStringOfApp)を保持する

設定ページで設定された時にその状態変数をセットする関数を引数として渡していく(俗に言うバケツリレー)
と言う感じで動きました。よければ参考にされていください。
ウィジェットツリーのネストが多層になるとバケツリレー用のコードを書く労力が増える、などのデメリットが大きくなるので「状態管理用パッケージを使う」という流れになると思いますが、基本なのでこの方法は確認しておいた方がいいのかな、とは思います。

//https://github.com/flutter/website/blob/main/examples/internationalization/minimal/lib/main.dart // Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // The pubspec.yaml file must include flutter_localizations in its // dependencies section. For example: // // dependencies: // flutter: // sdk: flutter // flutter_localizations: // sdk: flutter import 'dart:async'; import 'package:flutter/foundation.dart' show SynchronousFuture; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; class DemoLocalizations { const DemoLocalizations(this.locale); final Locale locale; static DemoLocalizations of(BuildContext context) { return Localizations.of<DemoLocalizations>(context, DemoLocalizations)!; } static const _localizedValues = <String, Map<String, String>>{ 'en': { 'title': 'Hello World', }, 'es': { 'title': 'Hola Mundo', }, 'ja': { 'title': 'こんにちは', }, }; static List<String> languages() => _localizedValues.keys.toList(); String get title { return _localizedValues[locale.languageCode]!['title']!; } } class DemoLocalizationsDelegate extends LocalizationsDelegate<DemoLocalizations> { const DemoLocalizationsDelegate(); @override bool isSupported(Locale locale) => DemoLocalizations.languages().contains(locale.languageCode); @override Future<DemoLocalizations> load(Locale locale) { return SynchronousFuture<DemoLocalizations>(DemoLocalizations(locale)); } @override bool shouldReload(DemoLocalizationsDelegate old) => false; } class DemoApp extends StatelessWidget { const DemoApp({ super.key, required this.setter, }); final void Function(String) setter; @override Widget build(BuildContext context) { return Scaffold( floatingActionButton: FloatingActionButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) { return EnvironmentSettings(setter: setter); },), ); }, ), appBar: AppBar( title: Text(DemoLocalizations .of(context) .title), ), body: Center( child: Text(DemoLocalizations .of(context) .title), ), ); } } class Demo extends StatefulWidget { const Demo({super.key}); @override State<Demo> createState() => _DemoState(); } class _DemoState extends State<Demo> { void setLocaleStringOfApp(String newValue) { setState(() { localeStringOfApp = newValue; }); } String localeStringOfApp = 'es'; @override Widget build(BuildContext context) { return MaterialApp( //↓これでアプリの言語を決められる。 //これを指定しない場合デバイスの言語設定を取ってくる。 locale: Locale(localeStringOfApp, ''), onGenerateTitle: (context) => DemoLocalizations .of(context) .title, localizationsDelegates: const [ DemoLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: const [ Locale('en', ''), Locale('es', ''), Locale('ja', ''), ], home: DemoApp( setter: setLocaleStringOfApp, ), ); } } void main() { runApp(const Demo()); } class EnvironmentSettings extends StatelessWidget { const EnvironmentSettings({ Key? key, required this.setter, }) : super(key: key); final void Function(String) setter; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('言語設定'), ), body: Center( child: Column( children: [ ElevatedButton( child: Text('日本語'), onPressed: () { setter('ja'); } ), SizedBox(height: 20.0,), ElevatedButton( child: Text('英語'), onPressed: () { setter('en'); } ), SizedBox(height: 20.0,), ElevatedButton( child: Text('スペイン語'), onPressed: () { setter('es'); } ), SizedBox(height: 20.0,), Text(DemoLocalizations .of(context) .title, ), ], ), ), ); } }

投稿2022/12/18 00:38

moriman

総合スコア615

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

RyuHo

2022/12/18 10:08

なるほど!このように関数を変数に入れてどんどん渡していくのですね!わかりやすかったです。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問