🪣
バケツリレーが役に立つこともある🪣
tips
ListViewをonTapすると詳細ページに、コンストラクターを使って値を渡す処理を書くことはよくある例ですが、詳細ページから他のページに値を渡す方法が思いつかなかった🫠
最近知った方法だとこんなのがある
- riverpodの.familyを使う.
- overrideWithValueを使う.
でもこの方法だと思いつかなかった???
実はすごく単純な方法で値を渡すことはできた。渡せばいいだけだから。
これが詳細ページだとする。ここにはTabBarが設置してあります。今回値を渡したいページはStopWatchPage
クラスです。こちらのクラスに引数が必須のコンストラクターを作りましょう💡
class FeedDetailPage extends HookConsumerWidget {
const FeedDetailPage({super.key, required this.taskState});
final TaskState taskState;
Widget build(BuildContext context, WidgetRef ref) {
final tabController = useTabController(initialLength: 2);
return Scaffold(
appBar: AppBar(
title: const Text('タスク詳細'),
bottom: TabBar(
controller: tabController,
tabs: const [
Tab(text: '手動入力'),
Tab(text: 'ストップウォッチ'),
],
),
),
body: TabBarView(
controller: tabController,
children: [
const ManualInputPage(),
StopWatchPage(taskState: taskState),
],
),
);
}
}
このようなコードを書くと、詳細ページから値を受け取ることができます。長いコードですいません🙇
class StopWatchPage extends HookConsumerWidget {
const StopWatchPage({super.key, required this.taskState});
final TaskState taskState;
Widget build(BuildContext context, WidgetRef ref) {
final stopWatchState = ref.watch(stopNotifierProvider);
final stopWatchController = ref.read(stopNotifierProvider.notifier);
return SafeArea(
child: Scaffold(
body: Padding(
padding: const EdgeInsets.all(16),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SizedBox(height: 40),
Text(
'タスク名',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black.withOpacity(0.6000000238418579),
fontSize: 12,
fontFamily: 'Roboto',
fontWeight: FontWeight.w400,
height: 0.11,
letterSpacing: 0.40,
),
),
const SizedBox(height: 16),
Center(
child: Text(
taskState.taskName,
style: const TextStyle(
fontSize: 20,
),
),
),
const SizedBox(height: 20),
Center(
child: Text(
"${stopWatchState.hours.toString().padLeft(2, '0')}:${stopWatchState.minutes.toString().padLeft(2, '0')}:${stopWatchState.seconds.toString().padLeft(2, '0')}",
style: const TextStyle(
fontSize: 78,
color: Colors.black,
fontWeight: FontWeight.w400,
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: SizedBox(
width: 70,
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFE0E6F2),
shape: const CircleBorder(
side: BorderSide(color: Colors.transparent),
),
),
onPressed: stopWatchState.started
? stopWatchController.stop
: stopWatchController.start,
child: Text(
stopWatchState.started ? '停止' : '開始',
style: const TextStyle(
color: Colors.indigo,
),
),
),
),
),
const SizedBox(width: 8),
Expanded(
child: SizedBox(
width: 70,
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFE0E6F2),
shape: const CircleBorder(
side: BorderSide(color: Colors.transparent),
),
),
onPressed: () {},
child: const Text(
'完了',
style: TextStyle(
color: Colors.indigoAccent,
),
),
),
),
),
const SizedBox(width: 8),
Expanded(
child: SizedBox(
width: 70,
height: 70,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFE0E6F2),
shape: const CircleBorder(
side: BorderSide(color: Colors.transparent),
),
),
onPressed: stopWatchController.reset,
child: const Text(
'リセット',
style: TextStyle(
color: Colors.indigoAccent,
),
),
),
),
),
],
),
],
),
),
),
),
);
}
}
こんな感じで表示できます:
まとめ
今回は分かり難い記事になってしまいましたが、重要な部分はコンストラクーがあれば、ListViewをonTapして詳細ページへモデルクラスの値を渡して、渡した値を他のページに渡したいときは、引数が必須のコンストラクターをつければ、Reactのpropsみたいに、値を他のページに簡単に渡すことができます。
想定されるユースケースとしては、特定のデータのリストを詳細ページに渡して表示できるけど、他のページにも表示したい場面で使うことができます。
Discussion