返回介绍

Send data to a new screen

发布于 2019-12-09 21:31:29 字数 6598 浏览 804 评论 0 收藏 0

Oftentimes, we not only want to navigate to a new screen, but also pass some data to the screen as well. For example, we often want to pass information about the item we tapped on.

Remember: Screens are Just Widgets™. In this example, we’ll create a List of Todos. When a todo is tapped on, we’ll navigate to a new screen (Widget) that displays information about the todo.

Directions

  1. Define a Todo class
  2. Display a List of Todos
  3. Create a Detail Screen that can display information about a todo
  4. Navigate and pass data to the Detail Screen

1. Define a Todo class

First, we’ll need a simple way to represent Todos. For this example, we’ll create a class that contains two pieces of data: the title and description.

class Todo {
  final String title;
  final String description;

  Todo(this.title, this.description);
}

2. Create a List of Todos

Second, we’ll want to display a list of Todos. In this example, we’ll generate 20 todos and show them using a ListView. For more information on working with Lists, please see the Basic List recipe.

Generate the List of Todos

final todos = List<Todo>.generate(
  20,
  (i) => Todo(
        'Todo $i',
        'A description of what needs to be done for Todo $i',
      ),
);

Display the List of Todos using a ListView

ListView.builder(
  itemCount: todos.length,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text(todos[index].title),
    );
  },
);

So far, so good. We’ll generate 20 Todos and display them in a ListView!

3. Create a Detail Screen that can display information about a todo

Now, we’ll create our second screen. The title of the screen will contain the title of the todo, and the body of the screen will show the description.

Since it’s a normal StatelessWidget, we’ll simply require that users creating the Screen pass through a Todo! Then, we’ll build a UI using the given 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. Navigate and pass data to the Detail Screen

With our DetailScreen in place, we’re ready to perform the Navigation! In our case, we’ll want to Navigate to the DetailScreen when a user taps on a Todo in our List. When we do so, we’ll also want to pass the Todo to the DetailScreen.

To achieve this, we’ll write an onTap callback for our ListTile Widget. Within our onTap callback, we’ll once again employ the Navigator.push method.

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]),
          ),
        );
      },
    );
  },
);

Complete example

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),
      ),
    );
  }
}

Passing Data Demo

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文