Flutter NavigationButtonの作り置き(UIのclass化)
ページが増えてきて迷子になる
「四次元年表」が迷路化してきた。
フロントページから入る。登録か検索かで分かれる。
登録が終わったらどこに行きたいか。
検索結果を見てから何をしたいか。
そういう動線について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はについてはこちら。
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だけになった。
使い方は一緒。
見た目こんな感じ。
少しずつ、少しずつ
今日も進んでいこう。
Discussion