teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

調査し直した内容に修正しました

2019/10/21 10:56

投稿

popobot
popobot

スコア6588

answer CHANGED
@@ -1,69 +1,19 @@
1
- > こ部分でFirstPageをリビルドしてoffstageに追加していのでしょうか?
1
+ **初期回答はリビルドしないと勘違いしていので、調査直した内容を修正しました...すみません**
2
2
 
3
+ 現時点(Flutter 1.9)では、`Navigator`で`push`や`pop`した際に、`Navigator`にスタックされているページは、リビルドされる仕様のようです。なお、リビルドを抑制するようなオプションは存在しないと思います
4
+ * `maintainState:false`にすることで、リビルドは抑制できますが、スタックされた遷移前のページは状態が破棄されるので、戻ったタイミングで初期状態でビルドされてます。これはこれでよくないケースがありそう
3
- 記事をベースに簡単なサンプルコードを書いて動かしてみましたが、リビルドていないようです
5
+ * `StatelessWidget`で構成されているケースリビルドしない場合もありました(回答履歴参照)
4
- ※画面遷移しても`rebuild`と出力されない
5
6
 
6
- ```
7
+ 詳しくは以下の本家のイシューに書かれています。
7
- import 'package:flutter/material.dart';
8
+ [https://github.com/flutter/flutter/issues/11655
9
+ ](https://github.com/flutter/flutter/issues/11655)
8
10
 
9
- void main() => runApp(MyApp());
11
+ イシューによれば、基本的に`Widget`の`build`は冪等性があり、リビルドされても同じ状態であれば、同じ結果を生成されるので、問題にはならない。ただし、パフォーマンス上よくないケースもあるので、今後何らかの対応があるかもしれないようです。
10
12
 
11
- class MyApp extends StatelessWidget {
13
+ 個人的には、特段パフォーマンス上の問題がなければ、リビルドされても気にしなくていい気がします。
12
- @override
13
- Widget build(BuildContext context) {
14
- return MaterialApp(
15
- title: 'Flutter Demo',
16
- home: FirstPage(),
17
- );
18
- }
19
- }
20
14
 
21
- class FirstPage extends StatelessWidget {
22
- @override
23
- Widget build(BuildContext context) {
24
- print('rebuild');
25
- return Scaffold(
26
- appBar: AppBar(title: Text('FirstPage')),
27
- body: Center(
28
- child: RaisedButton(
29
- child: Text('Next'),
30
- onPressed: () {
31
- Navigator.of(context).push(
32
- MaterialPageRoute(
33
- builder: (context) {
34
- return SecondPage();
35
- },
15
+ ---
36
- ),
37
- );
38
- },
39
- ),
40
- ),
41
- );
42
- }
43
- }
44
16
 
45
- class SecondPage extends StatelessWidget {
17
+ > この部分ではFirstPageをリビルドしてoffstageに追加しているのでしょうか?
46
- @override
47
- Widget build(BuildContext context) {
48
- return Scaffold(
49
- appBar: AppBar(title: Text('SecondPage')),
50
- body: Center(
51
- child: RaisedButton(
52
- child: Text('Back'),
53
- onPressed: () {
54
- Navigator.of(context).pop();
55
- },
56
- ),
57
- ),
58
- );
59
- }
60
- }
61
- ```
62
18
 
63
- > 3.アニメーション終了後、StackからFirstPageをoffstageに追加する
64
-
65
- 「StackからFirstPageをoffstage移動する」とう表現方が適切なのかもしれません(まり自信ないですが)
19
+ 厳密はリビルドして追加してではく、Navigatorスタックに変化がった場合に、リビルドが実行されるようです
66
-
67
- `Flutter Inspector`の`Render Tree`をみると、`Overlay`内部の`_RenderTheatre`で`Stack`と`Offstage`に分かれており、FirstPageは遷移前は`Stack`配下にいましたが、遷移後は`Offstage`配下にいました。より厳密にはソースコードを読めばわかるのかもですが難しい...
68
-
69
- ※記事を書いた方にも聞いてみるといいかもしれませんね

2

補足

2019/10/21 10:56

投稿

popobot
popobot

スコア6588

answer CHANGED
@@ -64,6 +64,6 @@
64
64
 
65
65
  「StackからFirstPageをoffstageに移動する」という表現の方が適切なのかもしれません(あまり自信ないですが)
66
66
 
67
- `Flutter Inspector`の`Render Tree`をみると、`Stack`と`Offstage`に分かれており、FirstPageは遷移前は`Stack`配下にいましたが、遷移後は`Offstage`配下にいました。より厳密にはソースコードを読めばわかるのかもです
67
+ `Flutter Inspector`の`Render Tree`をみると、`Overlay`内部の`_RenderTheatre`で`Stack`と`Offstage`に分かれており、FirstPageは遷移前は`Stack`配下にいましたが、遷移後は`Offstage`配下にいました。より厳密にはソースコードを読めばわかるのかもですが難しい...
68
68
 
69
69
  ※記事を書いた方にも聞いてみるといいかもしれませんね

1

補足

2019/10/20 21:59

投稿

popobot
popobot

スコア6588

answer CHANGED
@@ -66,4 +66,4 @@
66
66
 
67
67
  `Flutter Inspector`の`Render Tree`をみると、`Stack`と`Offstage`に分かれており、FirstPageは遷移前は`Stack`配下にいましたが、遷移後は`Offstage`配下にいました。より厳密にはソースコードを読めばわかるのかもです
68
68
 
69
- 記事を書いた方にも聞いてみるといいかもしれませんね
69
+ 記事を書いた方にも聞いてみるといいかもしれませんね