🚪
次のページに値を渡す
詳細画面に値を渡すには?
ListView.builderの公式ドキュメントを見ていたら、見つけたのですが、Classを型として、Listに格納して、画面に表示して、タップしたら、1だと1の詳細ページへ移動して、2だと2の詳細ページへ移動する仕組みをやっと理解できました😅
英語のコメントを翻訳して、このコードがどんな役割なのかも調べました。
コードは少ないですが、モデルと画面に分離したいので、分けました。
model/todo_model.dart
// モデルとなるクラスを作成する。
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
screen/detail_screen.dart
import 'package:flutter/material.dart';
import 'package:list_app/model/todo_model.dart';
class DetailScreen extends StatelessWidget {
// コンストラクタで、Todoを要求します。
const DetailScreen({super.key, required this.todo});
// Todoを保持するフィールドを宣言する。
final Todo todo;
Widget build(BuildContext context) {
// Todoを使用してUIを作成します。
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(todo.description),
),
),
);
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:list_app/model/todo_model.dart';
import 'package:list_app/screen/detail_screen.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
title: 'Passing Data',
home: TodosScreen(
todos: List.generate(
20,
(i) => Todo(
'Todo $i',
'Todoのために必要な説明文 $i',
),
),
),
);
}
}
class TodosScreen extends StatelessWidget {
const TodosScreen({super.key, required this.todos});
// クラスを型として使う
final List<Todo> todos;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Todos'),
),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// ユーザーがListTileをタップすると、DetailScreenに遷移する。
// DetailScreenを作成するだけでなく、次のことに注意してください。
// また、現在のTodoもそれに渡します。
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
やってみた感想
コンストラクターなるものをどうやって使うのか、公式ドキュメントを見て理解できた気がします。まずは公式ドキュメントを見てから、YouTubeやUdemyで勉強した方がいいのでしょうね。
おまけ
Freezedを使うとどうなるのか、試してみたくてやってみた。引数を追加しないとエラーが出てくる以外は特に変更はなさそうですね。
書き方が独特になっただけですね。
Freezedに変更
todo_model.dart
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';
part 'todo_model.freezed.dart';
part 'todo_model.g.dart';
class Todo with _$Todo {
const factory Todo({
required String title,
required String description,
}) = _Todo;
factory Todo.fromJson(Map<String, dynamic> json) =>
_$TodoFromJson(json);
}
main.dart
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
title: 'Passing Data',
home: TodosScreen(
todos: List.generate(
20,
(i) => Todo(description: 'Todo$i', title: 'Todoのために必要な説明文$i'),
),
),
);
}
}
Discussion