見出し画像

Flutter生活3日目 PageViewとTab

こんばんはファームノートの菅原です。
Flutter生活が3日目になりだんだんそれらしくなって来ました。
外はマイナス16度とかで手が痛くなります。

透明ボタン領域を作ってみました。

画面は全部画像を貼ってあるだけなので、ボタンとか押せません。
とりあえず押して画面遷移できるように透明コンテナーを上に重ねる必要がありました。
レイヤーってどうやるんだろうなーと調べたらありました。

Positionedで座標指定するんですねなるほどとホイホイレイアウトして、お次はタップだなーと漁ってみたところありました。

Widgetを囲むとWidgetの領域のジェスチャーを拾えるみたいです。
ジェスチャーと絵面を分けるのは無駄にコンポーネントに属性が増えてなくて素晴らしい設計だなと感心です。
こんなコードになりました。
タップ時に画面遷移するようにしてみました。

SingleChildScrollView(
      child: Stack(
        children: <Widget>[
          Image.asset('assets/NotificationList.png'),
          Positioned(
            left: 20.0,
            top: 20.0,
            right: 20.0,
            bottom: 100,
            child: GestureDetector(
              onTap: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => CowDetail()),
              ),
              child: Container(
                color: Colors.transparent,
              ),
...

縦スワイプでページ切り替えをしました。

動画の11秒あたりのところですが、FramerXでページコンポーネントというやつがあって便利だったのであるかなーと、Flutterのコンポーネントカタログみたらありました。
流石ですGoogleさん

おかげさまで割とそれ自体はサクサクできました。

ページングした先でタブ切り替えしました。

だいたいの環境では縦と横のスワイプが重なるとだいたい制御コードが死にそうに汚くなりがちなんですが、Flutterさんは一味違いました。
PageViewの要素の中に、DefaultTabControllerを配置したら、案の定ジェスチャーの優先度がうまく取れなくて、スワイプでのタブ切り替えできなかったんですが、入れ替えたらうまく行くかなと試してみたら、縦横スワイプがうまく共存できました。
更に、タブ内でスクロールを入れる感じで
縦スワイプページング -> 横スワイプ -> タブ切り替え -> 縦スクロール
がいい塩梅でハーモニーを奏でています。
ただ、縦スクロールが入るとページングができなくなっちゃうので、縦スクロール量が0の場合に上方向へのスワイプしたら、スクロールをロックするとかの機構を入れればなんとかなるんだろうなと思っています。

すごいですGoogle。

class CowDetail extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // タブのジェスチャーを優先するためPageViewの外側にTabControllerを配置
      body: DefaultTabController(
        length: 3,
        child: PageView(scrollDirection: Axis.vertical, children: <Widget>[
          Column(
            children: <Widget>[
              AppBar(
                backgroundColor: Colors.transparent,
                elevation: 0,
              ),
              Image.asset('assets/CowDetail-DashBoard.png'),
            ],
          ),
          Scaffold(
              appBar: AppBar(
                automaticallyImplyLeading: false,
                title: Text('Information'),
                bottom: TabBar(
                  tabs: [
                    Tab(text: "Home"),
                    Tab(text: "Breeding"),
                    Tab(text: "Helth"),
                  ],
                ),
              ),
              body: TabBarView(
                children: [
                  SingleChildScrollView(
                    child: Image.asset('assets/CowDetail-Basic.png'),
                  ),
                  SingleChildScrollView(
                    child: Image.asset('assets/CowDetail-Breeding.png'),
                  ),
                  SingleChildScrollView(
                    child: Image.asset('assets/CowDetail-Helth.png'),
                  ),

めっちゃ、楽

このペースで作れるなら正直ハイファイプロトのツールいらんです。

ファームノートでインタラクションデザイナーやってます。 最近はFigmaとFlutterでアプリを作っています。