LoginSignup
7
0

More than 3 years have passed since last update.

[Flutter] OffstageとStackでWidgetを切り替える

Last updated at Posted at 2020-10-06

はじめに

この記事では以下の画像のような,ボタンを押すことでWidgetを切り替える方法について説明しています。

2020-10-06 19.42のイメージ.jpg 2020-10-06 19.44のイメージ.jpg

この記事が参考になるかもしれない人

  • コピペで動くソースコードをいじることによってFlutterについて学習したい人
  • FlutterでWidgetの切り替えを行いたい人
  • StackでWidgetを重ねることによる実装が行いたい人
  • Offstageによる実装を行いたい人
  • 自分

前提知識

  • Columnで鉛直方向にWidgetを並べることができる。
  • mainAxisAlignment: MainAxisAlignment.centerでColumnに対し真ん中で鉛直方向に並べさせることができる。
  • StackでWidgetを重ねることができる。(Columnは鉛直方向,Rowは水平方向)
  • StatefulWidgetは変数の変更など動的な操作をする時に使う。

1.OffStageでWidgetを表示したり非表示にしたりできる

OffstageはレイアウトWidgetであり、表示/非表示を設定したいWidgetをchildに入れる。また,offstageに真偽値を指定し、falseの時に表示される。しかし、false/trueはいずれも固定されているものなので,表示/非表示を設定したいのであれば,ここにはbool型の変数を用いるべきだろう。
また,注意したいのがOffStageに格納されたWidgetは非表示にされた場合子要素のWidget自体が存在していないものとして扱われる。つまり、Columnなどの連続したものの中の一つにOffstageを入れた場合,非表示となったWidgetの部分は他のWidgetが詰めて配置されることとなる。

Offstage(
              offstage: show,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.red,
                ),
              )

2.Offstageだと詰められてしまうので,Stackを用意して対策する。

上述した通り,Offstageで書いた要素はパラメータoffstageがtrueの時元から存在していなかったものとして扱われてしまう。なので,その時には別のWidget(たとえば子要素が何もないContainer)を用意する必要がある。

Stack(
              children: <Widget>[
            Offstage(
              offstage: show,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.red,
                ),
              ),
            Offstage(
              offstage: !show,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.blue,
                ),
              ),
              ],
            ),

Stackの子要素集合にそれぞれOffstageWidgetのパラメータoffstageが偽の時と真の時を用意することで、配置がずれることなく表示/非表示を設定することができる。

ソースコード

コピペで動きます。(2020.10.6)

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool show = false;
  void showChange() {
    setState(() {show = !show;});
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Stack(
              children: <Widget>[
            Offstage(
              offstage: show,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.red,
                ),
              ),
            Offstage(
              offstage: !show,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.blue,
                ),
              ),
              ],
            ),
            Container(
               width: 100,
               height: 100,
               child: RaisedButton(
                 child: Text("変更"),
                 onPressed: showChange
                 ),
              ),
            ],
          ),
         ),
        ),
      );
  }
}
7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0