通常情況下,我們不僅希望導航到新的頁面,而且還希望將一些數據傳遞到頁面。例如,我們經常需要傳遞用戶點擊內容的信息。
請記住屏幕也是widget的一種,下面我們將創建一個ToDo列表。當一個todo被點擊,我們將導航到新的頁面(widget)來顯示todo
介紹
- 定義個Todo類
- 顯示一個Todo列表
- 創建一個詳細頁面來顯示todo信息
- 導航并且傳遞數據想詳情頁面
1. 定義Todo類
class Todo {
final String title;
final String description;
Todo(this.title, this.description);
}
2. 創建一個List
class Todo {
final String title;
final String description;
Todo(this.title, this.description);
}
3. 使用ListView顯示List
ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
);
},
);
4. 創建一個詳情頁面來顯示todo的詳細信息
現在,我們將創建第二個頁面。頁面的title將像是todo的標題,并且頁面的body將顯示詳細信息。
由于這個是一個普通的StatelessWidget,我僅需要一個頁面來傳遞todo信息。
class DetailScreen extends StatelessWidget {
// Declare a field that holds the Todo
final Todo todo;
// In the constructor, require a Todo
DetailScreen({Key key, @required this.todo}) : super(key: key);
@override
Widget build(BuildContext context) {
// Use the Todo to create our UI
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Text(todo.description),
),
);
}
}
4. 導航同時傳遞數據的到詳情頁面
我們的詳情頁面已經準備好了,我們將執行導航。在這個案例中,我們要實現用戶點擊Todo List后跳轉的詳情頁面,同時還要傳遞數據到詳情頁面。
為了要達到這個效果,我為ListTile Widget寫了一個onTap回調函數。在onTap函數中我們使用了Navigator.push 方法。
ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps on the ListTile, navigate to the DetailScreen.
// Notice that we're not only creating a DetailScreen, we're
// also passing the current todo to it!
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
);
完整代碼如下
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class Todo {
final String title;
final String description;
Todo(this.title, this.description);
}
void main() {
runApp(MaterialApp(
title: 'Passing Data',
home: TodosScreen(
todos: List.generate(
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
),
),
));
}
class TodosScreen extends StatelessWidget {
final List<Todo> todos;
TodosScreen({Key key, @required this.todos}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Todos'),
),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps on the ListTile, navigate to the DetailScreen.
// Notice that we're not only creating a DetailScreen, we're
// also passing the current todo through to it!
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
class DetailScreen extends StatelessWidget {
// Declare a field that holds the Todo
final Todo todo;
// In the constructor, require a Todo
DetailScreen({Key key, @required this.todo}) : super(key: key);
@override
Widget build(BuildContext context) {
// Use the Todo to create our UI
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Text(todo.description),
),
);
}
}
運行效果
todo list