通常情况下,我们不仅希望导航到新的页面,而且还希望将一些数据传递到页面。例如,我们经常需要传递用户点击内容的信息。
请记住屏幕也是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),
),
);
}
}
运行效果