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

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

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

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

Dart

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

Q&A

解決済

1回答

4389閲覧

Dart: Widget部分とメソッド部分でファイル分割をしたい

tmsah

総合スコア101

Flutter

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

Dart

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

0グッド

1クリップ

投稿2021/03/01 00:57

Dart初心者です。
Widget部分の記述とメソッド部分の記述でファイル分割をしたいと考えています。

現在、チュートリアルを見ながらDartの勉強を進めているところです。
具体的には、StatefulWidget内でユーザーのアクションに合わせて画面を変更させています。

Dart

1class A extends StatefulWidget { 2 A({Key key}) : super(key: key); 3 4 AState createState() => AState(); 5} 6 7class AState extends State<A> { 8 9 String func1(int n) { 10 // (略) // 11 return str; 12 } 13 14 void func2() { 15 setState(() { 16 // (略) // 17 }); 18 } 19 20 void func3() { 21 setState(() { 22 // (略) // 23 }); 24 } 25 26 27 Widget build(BuildContext context) { 28 return Container( 29 // (略) // 30 RaisedButton( 31 onPressed: func2, 32 ), 33 NumberPicker.integer( 34 onPressed: func3, 35 ), 36 // (略) // 37 ); 38 } 39}

同じファイル内にメソッド記述とWidget記述があると読みにくくなるので、これらを別ファイルに分割したいと考えています。
このとき、メソッド部分(func1から3)だけを取り出すことはできるのでしょうか。
特にfunc2と3はユーザーからのイベントを受けて、中でsetStateを行っているため、ここだけ分離することができるのか疑問です。
メソッドはグローバルで宣言するとどこからでも参照できるようになってしまうので、一つのファイルからimportextendで読み込みたいと考えています。

Dartではそもそもこんなことをする想定がされていないのでしょうか。
その場合はどのようにファイル分割を行うのが適切なのでしょうか。
メソッド、Widgetそれぞれが長くなってしまうことは諦めて、より細かい部品単位でWidgetを分けていくしかないのでしょうか。

よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

メソッドはクラスの中で作成するものだと思います。
setStateは状態(state)を持つクラスの中でのみ使えるはずなので、別ファイルでsetStateを含むメソッドを記述していたとしても、流用することは難しいと考えます。
以上を前提に、3つほどsetStateを活用したパターンを作ってみました。

①メソッド切り出しパターン
②クラスとしてcomponentを分割するパターン
③setStateの中で、関数の戻り値を応用するパターン

印象としては②が一般的かと思います。可読性もよく、パフォーマンスも優れていると思います。

home_screen.dart

dart

1import 'package:flutter/material.dart'; 2import 'package:method_test_app/component.dart'; 3import 'utilities.dart'; 4 5class HomeScreen extends StatefulWidget { 6 7 _HomeScreenState createState() => _HomeScreenState(); 8} 9 10class _HomeScreenState extends State<HomeScreen> { 11 String _message; 12 13 14 void initState() { 15 // TODO: implement initState 16 super.initState(); 17 _message = ""; 18 } 19 20 21 Widget build(BuildContext context) { 22 23 return Scaffold( 24 appBar: AppBar( 25 title: Text("テスト"), 26 ), 27 body: Center( 28 child: Padding( 29 padding: const EdgeInsets.all(20.0), 30 child: Column( 31 mainAxisAlignment: MainAxisAlignment.spaceEvenly, 32 children: [ 33 //メソッドとして切り出しパターン 34 SizedBox( 35 width: double.infinity, 36 child: RaisedButton( 37 color: Colors.brown, 38 onPressed: () => sayHallo(), 39 child: Text("Function A"), 40 ), 41 ), 42 //クラスとして別ファイルに切り出すパターン 43 ReusableButton( 44 color: Colors.brown, 45 onPressed: () { 46 setState(() { 47 _message = "ありがとう"; 48 }); 49 }, 50 ), 51 //関数を別ファイルに切り出すパターン 52 SizedBox( 53 width: double.infinity, 54 child: RaisedButton( 55 color: Colors.brown, 56 onPressed: () { 57 setState(() { 58 _message = editMessage(message: _message); 59 }); 60 }, 61 child: Text("Function C"), 62 ), 63 ), 64 Text(_message) 65 ], 66 ), 67 ), 68 ), 69 ); 70 } 71 72 //メソッドとして切り出しパターン(続き) 73 sayHallo() { 74 setState(() { 75 print("テスト"); 76 _message = "こんにちわ"; 77 }); 78 } 79} 80

components.dart
新しくReusableButtonを作成しています。その中で、VoidCallback(戻り値のないタイプの関数)を変数として組み込んでいます。

dart

1import 'package:flutter/material.dart'; 2 3class ReusableButton extends StatelessWidget { 4 final VoidCallback onPressed; 5 final Color color; 6 7 ReusableButton({ this.onPressed, this.color}); 8 9 10 Widget build(BuildContext context) { 11 return SizedBox( 12 width: double.infinity, 13 child: RaisedButton( 14 onPressed: onPressed, color: color, child: Text("Function B")), 15 ); 16 } 17} 18

utilities.dart
変数messageの内容を引数として受け取り、String型の戻り値を返しています。

dart

1import 'package:flutter/material.dart'; 2 3String editMessage({ String message}) { 4 return "太郎くん${message}"; 5}

投稿2021/03/02 09:18

編集2021/03/02 09:26
Rassy

総合スコア44

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

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

tmsah

2021/03/02 10:48

丁寧な回答ありがとうございます。 やはり私が想定していた書き方は一般的ではないのですね... ②で細かく部品化しつつ、同じファイル内で切り出したメソッドの返り値をsetState内で使う①③のハイブリッドのような記述がいいのかなと思いました。 ②で切り出ししても、結局onPress内でsetStateしていたらその処理は元のファイル(home_screen.dart)に記述しないとダメということになりますね。 切り出した先で(③のように)メソッドを定義しておいてそれを呼び出して値を返す、というのもありな気がしますけど、それも結局メソッドのネスト内にsetStateが必要になったりしたらダメなので、一般性の面でもよろしくないなと思いました。 勉強になりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問