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

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

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

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

Dart

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

Q&A

解決済

2回答

4634閲覧

Dart/Flutterにおいて、他ファイルのstateが更新される度に値を利用する方法

neoz

総合スコア31

Flutter

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

Dart

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

0グッド

1クリップ

投稿2020/09/19 02:24

Flutterアプリにおいて、他ファイルのstateが更新される度に値を利用するにはどうすれば良いでしょうか。

//ファイル1
こちらでアイコンがクリックされる度に、posが変更されます。(確認済み)

Dart

1class Nav extends StatefulWidget { 2 3 _NavState createState() => _NavState(); 4} 5 6class _NavState extends State<Nav> { 7 int pos = 0; 8} 9 10 11 Widget build(BuildContext context) { 12 return Row(中略 13  return GestureDetector( 14 onTap: () { 15 setState(() { 16 items.forEach((item) => item.isOpen = false); 17 i.isOpen = !i.isOpen; 18 pos = i.pos; 19 }); 20 }, 21

//ファイル2
ファイル1のpos変更に応じて、ファイル2の_indexを変更したいのですが
どのように双方を結びつければ良いかがわかりません。
stateの_を消して直接ファイル1のposを呼んでみたり、二つを同じファイルに書いてonTapで更にsetStateを使い、MyAppState内の_indexを更新しようとしましたが、

目指す姿である、ファイル1のアイコンがクリックされると同時に、ファイル2にある_indexの値がposに置き換わる、というのを実現できていません。

Dart

1class Homepage extends StatefulWidget { 2 3 MyAppState createState() => MyAppState(); 4} 5 6class MyAppState extends State<Homepage> { 7 int _index = 0; 8 9Widget build(BuildContext context) { 10 return Scaffold( 11 Nav()

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

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

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

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

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

guest

回答2

0

ベストアンサー

providerや、blocパターンなどの状態管理を導入するのが自然です。

状態管理というのは、アプリの状態を表す1つの変数を複数のWidget間で共有するための仕組みのことです。


もしこれらを使わず、setStateのみで実装するのであれば、

  • indexという値はHomeで管理し、コンストラクタでNavにも渡す
  • index更新用の関数をNavにも渡す

というのが初心者にとって分かりやすい手法かと思います。

質問内容にあるように、HomeNavで別々に変数を宣言して、双方を結びつけるというのは無理です。

dart

1class Home extends StatefulWidget { 2 3 _HomeState createState() => _HomeState(); 4} 5 6class _HomeState extends State<Home> { 7 int _index = 0; 8 9 void setIndex(int index) { 10 setState(() { 11 this._index = index; 12 }); 13 } 14 15 16 Widget build(BuildContext context) { 17 return Scaffold( 18 appBar: AppBar(), 19 body: Column( 20 children: [ 21 Nav( 22 pos: _index, 23 setIndex: (int i) => setIndex(i), 24 ), 25 Text('$_index'), 26 ], 27 ), 28 ); 29 } 30} 31 32class Nav extends StatefulWidget { 33 final int pos; 34 final Function(int) setIndex; 35 36 const Nav({ 37 Key key, 38 this.pos, 39 this.setIndex, 40 }) : super(key: key); 41 42 43 _NavState createState() => _NavState(); 44} 45 46class _NavState extends State<Nav> { 47 Widget navButton(int index) { 48 return RaisedButton( 49 child: Text('$index'), 50 onPressed: () { 51 widget.setIndex(index); 52 }, 53 ); 54 } 55 56 57 Widget build(BuildContext context) { 58 print('pos: ${widget.pos}'); 59 return Row( 60 children: [ 61 navButton(0), 62 navButton(1), 63 navButton(2), 64 ], 65 ); 66 } 67} 68

投稿2020/09/20 00:46

nskhei

総合スコア704

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

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

toast-uz

2020/09/20 00:51

新しい方の投稿に、stateだけの例として、この方針を書こうとしていたところでした。とてもよくまとまっていて、よい回答だと思います。
nskhei

2020/09/20 01:17

同じ回答しても意味がないと思ったので、そちらにはproviderを使った方法を書きました。
toast-uz

2020/09/20 01:17

ありがとうございます。
neoz

2020/09/20 03:17

nskhei様、toast-uz様、ご回答頂きありがとうございました。お力添えにより、目指す姿で動かすことができました。 state/provider双方のやり方をご教示頂け勉強になりました。 今は目下の問題解決が優先でしたが、今後じっくり背景にあるFlutterのロジックも勉強していくようにします。
guest

0

「二つを同じファイルに書いてonTapで更にsetStateを使い、MyAppState内の_indexを更新」でよいと思います。ただし、_indexはonTap()のスコープからもアクセスできるみように、class MyAppStateの外にトップレベルで定義してください。

Dart

1int _index = 0; 2 3class MyAppState extends State<Homepage> { 4 _index = 0; 5 67 8 onTap: () { 9 setState(() { 10 items.forEach((item) => item.isOpen = false); 11 i.isOpen = !i.isOpen; 12 pos = i.pos; 13 _index = pos; 14 15 });

投稿2020/09/19 13:55

toast-uz

総合スコア3266

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

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

neoz

2020/09/19 15:29

ありがとうございます。ただ、どうもこれだと外側の_indexは変わりますが、state内の_indexは変わらず、利用したいのはstate内のindexの監視・変更により描画するものを選択、することなので このままだとだめそうです。。 onTap()の中身を pos = i.pos; MyAppState()._index = pos; print(MyAppState()._index); として、stateの_indexを直接変えようとしましたが初期値のままでした。
toast-uz

2020/09/19 23:52

「ファイル1のアイコンがクリックされると同時に、ファイル2にある_indexの値がposに置き換わる」は実現できたけど、質問文に書かれていない、まだ実現したいことがある、ということでしょうか? 質問文を正しく修正ください。「state内の_index」というのは、コードのどこにも表現されていません。
toast-uz

2020/09/20 00:04

おそらく、Widgetをコンポーネント化して(できれば)別ファイルに配置したい、その際、状態やUIイベントを、親子間で必要に応じて共有したい、ということをやりたいのかと思います。 私も詳しくありませんが、InheritedWidgetとかProviderとか言われる領域のテクニックになりますので、一度それらを学習してみてはいかがでしょうか?
neoz

2020/09/20 00:27

ありがとうございます。言葉足らずだったのと、widgetを1ファイルにまとめたため質問の趣旨が異なってきたので、新しい質問を立てました。 https://teratail.com/questions/292962?modal=q-comp おっしゃるとおり、私も調べる中でそのあたりの技術に行き当たったのですが、今回のstatefulで作っているコードをどう適用したらいいかわからず、模索している状況です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問