新しい画面に移動するだけでなく、その画面にデータを渡したいこともよくあります。
(例えば、タップされた項目に関する情報を渡したい場合があります。)
1.Todo クラスの定義
まず、Todo クラス(メンバ: タイトル、詳細データ)を作成します。
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
2.Todo リストの作成
次に、Todo リスト(データ件数:20(固定))を作成します。
final todos = List.generate(
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
);
そして、上記の Todo リスト を、ListView により、リスト表示します。
ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
);
},
)
3.リスト表示用 Todo 画面の作成
上記実装の為に、StatelessWidget (ここでは以下コード中の TodosScreen )を作成します。
・(このページ内容は実行時に変更されない為)ウィジェットのスコープ内で Todo のリストを要求する必要があります。
・build() の body に ListView.builder を渡します。
これでリストが画面にレンダリングされ、実行できるようになります。
class TodosScreen extends StatelessWidget {
//Todos リストをコンストラクタで渡す。
const TodosScreen({super.key, required this.todos});
final List<Todo> todos;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Todos'),
),
//Todos をリスト表示する。
//( build() に返すウィジェットの body に ListView.builder を渡します )
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
);
},
),
);
}
}
4.Todo関連情報表示用詳細画面の作成
ここでは「Todo」の詳細情報を表示する画面の作成について触れています。
(1)DetailScreenクラスの作成
まず、StatelessWidget クラス( 以下の DetailScreen )を作成します。
このクラスの目的は、渡された「Todo」オブジェクトの詳細情報(タイトルと説明)を表示することです。
詳細画面は、新しい画面として表示され、具体的な情報はユーザが選択した「Todo」から受け取ります。
class DetailScreen extends StatelessWidget {
//コンストラクタでTodoオブジェクトを受け取ります。
const DetailScreen({super.key, required this.todo});
//Todoオブジェクトを保持するフィールドを宣言。
final Todo todo;
(2)コンストラクタでTodoオブジェクトを渡す
DetailScreen のコンストラクタでは、required を使用して Todo オブジェクトを受け取ります。このオブジェクトには「Todo」のタイトルや説明が格納されています。
(3)UIの構築
build メソッドでUIを作成します。以下の要素を構成しています。
- AppBar
上部には「Todo」のタイトルが表示されます。
これは todo.title を使用して動的に設定されます。 - Padding
コンテンツを画面の端から一定の距離に配置する為にパディングを使用します。 - Textウィジェット
todo.description に基づいて、「Todo」の説明が表示されます。
@override
Widget build(BuildContext context) {
//Todoオブジェクトを使ってUIを作成します。
return Scaffold(
appBar: AppBar(
title: Text(todo.title), //Todoのタイトルを表示
),
body: Padding(
padding: const EdgeInsets.all(16), //16pxの余白を追加
child: Text(todo.description), //Todoの説明を表示
),
);
}
}
- Todoオブジェクト
この DetailScreen では Todo オブジェクトを受け取り、そのオブジェクトのタイトルと説明を表示します。 - シンプルな画面構成
基本的に AppBar と Text ウィジェットを組み合わせ、シンプルに情報を表示します。
Padding で適切な余白を確保することで、視覚的に見やすくしています。
5.詳細画面に移動してデータを渡す
リスト内の項目(todo)をタップすると詳細画面(DetailScreen)に遷移し、選択した項目のデータをその画面に渡す手順です。
(1)ユーザーのタップを検出する
TodosScreenでリスト項目をタップした際に詳細画面に遷移する様に、ListTile ウィジェットの onTap コールバックを使用します。
ここで、タップされた項目に対応する todo データを DetailScreen に渡します。
body: ListView.builder(
itemCount: todos.length, //リストの項目数
itemBuilder: (context, index) {
return ListTile(
//各項目のタイトルを表示
title: Text(todos[index].title),
//ListTile タップ時 DetailScreen に遷移する
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
//DetailScreenに todo オブジェクトを渡す
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
(2)Navigator.push() メソッドの利用
タップされた際に、Navigator.push() を呼び出して( DetailScreen に )遷移します。
(ここで、新しいルート(画面)をスタックに積むことで遷移が行われます。
このメソッドの builder パラメータで、DetailScreen を作成し、todo データを渡しています。)
- Navigator.push
新しい画面を現在の画面の上に積むメソッドです。
(ここでは、詳細画面が表示されます。) - MaterialPageRoute
このオブジェクトを使用して、画面遷移時のアニメーション等を定義します。
(タップされた todo オブジェクトが 遷移先(DetailScreen) に渡されます。)