傳送資料到新畫面
- 1. 定義一個待辦事項類別
- 2. 建立一個待辦事項列表
- 3. 建立一個待辦事項螢幕來顯示列表
- 4. 建立一個詳細螢幕來顯示待辦事項的資訊
- 5. 導航並將資料傳遞到詳細螢幕
- 或者,使用 RouteSettings 傳遞引數
通常,您不僅希望導航到新的螢幕,還希望將資料傳遞到該螢幕。例如,您可能希望傳遞有關已點擊項目的資訊。
請記住:螢幕只是 Widget。在此範例中,建立一個待辦事項列表。當點擊一個待辦事項時,導航到一個新的螢幕(Widget),該螢幕顯示有關該待辦事項的資訊。此食譜使用以下步驟
- 定義一個待辦事項類別。
- 顯示待辦事項列表。
- 建立一個可以顯示待辦事項資訊的詳細螢幕。
- 導航並將資料傳遞到詳細螢幕。
1. 定義一個待辦事項類別
#首先,您需要一個簡單的方法來表示待辦事項。在此範例中,建立一個包含兩個資料片段的類別:標題和描述。
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
2. 建立一個待辦事項列表
#其次,顯示待辦事項列表。在此範例中,產生 20 個待辦事項,並使用 ListView 顯示它們。有關使用列表的更多資訊,請參閱使用列表食譜。
產生待辦事項列表
#final todos = List.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
。我們稱之為 TodosScreen
。由於此頁面的內容在執行期間不會變更,因此我們必須在此 Widget 的範圍內要求待辦事項列表。
我們將 ListView.builder
作為我們返回給 build()
的 Widget 的主體傳入。這會將列表呈現到螢幕上,讓您可以開始使用!
class TodosScreen extends StatelessWidget {
// Requiring the list of 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'),
),
//passing in the ListView.builder
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
);
},
),
);
}
}
使用 Flutter 的預設樣式,您可以順利進行,而無需為您以後想做的事情煩惱!
4. 建立一個詳細螢幕來顯示待辦事項的資訊
#現在,建立第二個螢幕。螢幕的標題包含待辦事項的標題,螢幕的主體顯示描述。
由於詳細螢幕是正常的 StatelessWidget
,因此要求使用者在 UI 中輸入 Todo
。然後,使用給定的待辦事項建立 UI。
class DetailScreen extends StatelessWidget {
// In the constructor, require a Todo.
const DetailScreen({super.key, required this.todo});
// Declare a field that holds the Todo.
final Todo todo;
@override
Widget build(BuildContext context) {
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
5. 導航並將資料傳遞到詳細螢幕
#有了 DetailScreen
後,您就可以執行導航了。在此範例中,當使用者點擊列表中的待辦事項時,導航到 DetailScreen
。將待辦事項傳遞到 DetailScreen
。
若要擷取使用者在 TodosScreen
中的點擊,請為 ListTile
Widget 撰寫 onTap()
回呼。在 onTap()
回呼中,使用 Navigator.push()
方法。
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps the ListTile, navigate to the DetailScreen.
// Notice that you're not only creating a DetailScreen, you're
// also passing the current todo through to it.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
互動式範例
#import 'package:flutter/material.dart';
class Todo {
final String title;
final String description;
const 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 {
const TodosScreen({super.key, required this.todos});
final List<Todo> todos;
@override
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),
// When a user taps the ListTile, navigate to the DetailScreen.
// Notice that you're not only creating a DetailScreen, you're
// also passing the current todo through to it.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
class DetailScreen extends StatelessWidget {
// In the constructor, require a Todo.
const DetailScreen({super.key, required this.todo});
// Declare a field that holds the Todo.
final Todo todo;
@override
Widget build(BuildContext context) {
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
或者,使用 RouteSettings 傳遞引數
#重複前兩個步驟。
建立一個詳細螢幕來提取引數
#接下來,建立一個詳細螢幕,從 Todo
中提取並顯示標題和描述。若要存取 Todo
,請使用 ModalRoute.of()
方法。此方法會傳回具有引數的目前路由。
class DetailScreen extends StatelessWidget {
const DetailScreen({super.key});
@override
Widget build(BuildContext context) {
final todo = ModalRoute.of(context)!.settings.arguments as Todo;
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
導航並將引數傳遞到詳細螢幕
#最後,當使用者使用 Navigator.push()
點擊 ListTile
Widget 時,導航到 DetailScreen
。將引數作為 RouteSettings
的一部分傳遞。DetailScreen
會提取這些引數。
ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps the ListTile, navigate to the DetailScreen.
// Notice that you're not only creating a DetailScreen, you're
// also passing the current todo through to it.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DetailScreen(),
// Pass the arguments as part of the RouteSettings. The
// DetailScreen reads the arguments from these settings.
settings: RouteSettings(
arguments: todos[index],
),
),
);
},
);
},
)
完整範例
#import 'package:flutter/material.dart';
class Todo {
final String title;
final String description;
const 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 {
const TodosScreen({super.key, required this.todos});
final List<Todo> todos;
@override
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),
// When a user taps the ListTile, navigate to the DetailScreen.
// Notice that you're not only creating a DetailScreen, you're
// also passing the current todo through to it.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DetailScreen(),
// Pass the arguments as part of the RouteSettings. The
// DetailScreen reads the arguments from these settings.
settings: RouteSettings(
arguments: todos[index],
),
),
);
},
);
},
),
);
}
}
class DetailScreen extends StatelessWidget {
const DetailScreen({super.key});
@override
Widget build(BuildContext context) {
final todo = ModalRoute.of(context)!.settings.arguments as Todo;
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
除非另有說明,否則本網站上的文件反映了 Flutter 的最新穩定版本。頁面最後更新時間為 2024-06-26。 檢視原始碼 或 回報問題。