在开发的过程中,我们经常需要在跳转到新页面的时候,能同时传递一些数据。比如,传递用户点击的元素信息。
还记得么,全屏的界面也只是 Widget。在这个例子中,我们会创建一个待办事项列表, 当某个事项被点击的时候,会跳转到新的一屏 (Widget),在新的一屏显示待办事项的详细信息。
步骤
定义一个描述待办事项的数据类
用列表 (List Widget) 显示待办事项
创建一个显示待办事项详细信息的界面
传递数据并跳转到待办事项详细信息界面
1. 定义一个描述待办事项的数据类
首先,我们需要一个简单的方式来描述待办事项。我们创建一个类叫做 Todo
,包含 title
和description
两个成员变量。
class Todo {
final String title;
final String description;
Todo(this.title, this.description);
}
2. 创建待办事项列表
第二步,我们需要显示一个待办事项列表,生成 20 条待办事项并用 ListView
显示。如果你想了解更多关于列表显示的内容,请阅读文档 基础列表
。
生成待办事项列表
final todos = List<Todo>.generate(
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
);
用 ListView 显示待办事项列表
ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
);
},
);
到目前为止, 我们生成了 20 条待办事项, 并用 ListView
把它显示出来了。
3. 创建一个显示待办事项详细信息的界面
现在,我们来创建第二个全屏的界面, 界面的标题是待办事项的标题, 界面下面显示待办事项的描述信息。
这个界面是一个 StatelessWidget
,创建的时需要传递 Todo
对象给它, 它就可以使用传给他的 Todo
对象来构建 UI 。
class DetailScreen extends StatelessWidget {
// 声明一个成员变量来保存 Todo 对象 (Declare a field that holds the Todo)
final Todo todo;
// 构造函数需要 Todo 对象 (In the constructor, require a Todo)
DetailScreen({Key key, @required this.todo}) : super(key: key);
@override
Widget build(BuildContext context) {
// 使用 Todo 对象构建 UI (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. 传递数据并跳转到待办事项详细信息界面
上面写完了 DetailScreen
,现在该执行界面跳转啦!我们想让用户在点击列表中的某个待办事项时跳转到 DetailScreen
界面,同时能传递点击的这条代办事项对象(Todo
对象) 。
想要实现这些,我们来编写 ListTile
widget 的 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),
),
);
}
}
当前内容版权归 flutter-io.cn 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 flutter-io.cn .