🧩

Flutter NavigationButtonの作り置き(UIのclass化)

2024/03/15に公開

ページが増えてきて迷子になる

「四次元年表」が迷路化してきた。
フロントページから入る。登録か検索かで分かれる。
登録が終わったらどこに行きたいか。
検索結果を見てから何をしたいか。
そういう動線についてTestUserからきた苦情が
AppBarにdefaultで付いてる戻るButtonだ。
単純な戻るButtonなので、どこから来たかによって、戻る場所が変わってくる。
これは迷子の元。

AppBarの構造

今まであんまり真面目に考えたことはなかったのだが、
AppBarは leading(左側)、title(中央)、action(右側)でできている。
右側は割に簡単にカスタマイズできるが、今回は左側を使う。
defaultでは、表面上なんの記述もなしに戻るボタンがある。
試しにleadingと指定してtextButtonを置き、遷移先も指定してみる。
できないことはないが、textのレイアウトが変。
そもそもシンプルな < アイコンだけの幅しか取ってないらしい。
なのでleadingWidthで幅指定もする。

あっちこっちで使うんだしclass化しよう

で、まずつくったのがこちら

import 'package:flutter/material.dart';
import 'shadowed_container.dart';

class NavigationButton extends StatelessWidget {
  final Widget destinationPage;
  final String buttonText;

  const NavigationButton({
    super.key,
    required this.destinationPage,
    required this.buttonText,
  });

  
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: ShadowedContainer(
        child: TextButton(
          style: TextButton.styleFrom(backgroundColor: Colors.blueGrey),
          child: Text(buttonText, style: const TextStyle(color: Colors.white)),
          onPressed: () => Navigator.push<String>(
            context,
            MaterialPageRoute(builder: (context) => destinationPage),
          ),
        ),
      ),
    );
  }
}

ShadowedContainerはについてはこちら。
https://zenn.dev/flutteruniv_dev/articles/a9b59ec60f6320
ここでは、textButtonに表示する文字と遷移先を引数にしている。
leadingWidthは、実際に使うページで、textの長さに応じて設定する。
例えばこんな感じ。

        appBar: AppBar(
          backgroundColor: Colors.grey[200],
          leading: const NavigationButton(
            destinationPage: MultiSearchPage(),
            buttonText: 'search again',
          ),
          leadingWidth: 150,
          title: const Text('CLASSIC VIEW'),
          actions: const [
            NavigationButton(
                destinationPage: TabPage(),
                buttonText: 'add a new event')
        ],
        ),

ここでは右側のactionsの中にもButtonを置いているけど、
こちらは幅指定しなくても勝手にうまくいく。

Popで戻りたいこともあると判明

遷移先を指定するんだから、どこにでも行ける。
それはそうなんだが、一つ困ったことが起きた。
検索結果一覧のページから、一つの結果の詳細を表示するページに遷移して
そこから戻ろうとしたとき、
上記のButtonでは、検索結果が消えてしまうのだ。
検索結果一覧ページが要求している「検索結果」という引数がないから。
でも、ただの戻るButtonで戻れば、一覧はまだそこに残っている。
で、あとは好みの問題。
defaultの戻るButtonを使うか、
見た目、NavigationButtonとお揃いのButtonにするか。
ということで、もう一つ作ったボタンがこちら。

class PopBackButton extends StatelessWidget {
  final String buttonText;

  const PopBackButton({
    super.key,
    required this.buttonText,
  });

  
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: ShadowedContainer(
        child: TextButton(
          style: TextButton.styleFrom(backgroundColor: Colors.blueGrey),
          child: Text(buttonText, style: const TextStyle(color: Colors.white)),
          onPressed: () => Navigator.of(context).pop(),
          ),
        ),
    );
  }
}

onPressedの設定を変えて、引数は表示するTextだけになった。
使い方は一緒。
見た目こんな感じ。

少しずつ、少しずつ

今日も進んでいこう。

Flutter大学

Discussion