Flutter学习

Flutter路由导航传递参数

2019-04-21  本文已影响0人  zqyadam

描述

一个列表页面,点击每个列表项进入不同的详情页面,并将列表的信息(标题和描述)传递过去

列表页面及详情页面

列表页面
详情页面

代码

主页面

// main.dart
import 'package:flutter/material.dart';
import 'ProductDetailPage.dart';
import 'ProductListPage.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      home: ProductListView(),
      // 使用Navigator.push时,不需要下面的路由表
      routes: <String, WidgetBuilder>{
        'list': (BuildContext context) => ProductListView(),
        'detail': (BuildContext context) => ProductDetailPage(),
      },
    );
  }
}

列表页面

// ProductListPage.dart
import 'package:flutter/material.dart';
import 'Model/ProductClass.dart';
import 'ProductDetailPagePushNamed.dart';
import 'ProductDetailPagePush.dart' as ProductPush;

class ProductListView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('商品列表'),
      ),
      body: ProductList(
        products: List.generate(100, (index) {
          return Product('商品$index', '这是一个商品$index');
        }),
      ),
    );
  }
}

class ProductList extends StatelessWidget {
  final List<Product> products;
  ProductList({Key key, @required this.products}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: products.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(products[index].name),
          subtitle: Text(products[index].description),
          onTap: () {
            /* using pushNamed */
            Navigator.pushNamed(context, 'detail', arguments: products[index]);
            /* using push */
/*             Navigator.push(context, MaterialPageRoute(
              builder: (context)=>ProductPush.ProductDetailPage(product:products[index]),
            ));
 */          },
        );
      },
    );
  }
}

详情页面

1)使用Navigator.pushNamed方法

使用Navigator.pushNamed方法首先需要在MaterialApp中定义routes

参数传递参看:https://flutter.dev/docs/cookbook/navigation/navigate-with-arguments

// ProductDetailPagePushNamed.dart
import 'package:flutter/material.dart';
import 'Model/ProductClass.dart';

class ProductDetailPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    /* 接收参数 */
    final Product product = ModalRoute.of(context).settings.arguments;
    return Scaffold(
      appBar: AppBar(
        title: Text(product.name),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            Text(product.description),
            RaisedButton(
              child: Text('返回'),
              onPressed: () {
                Navigator.pop(context);
              },
            )
          ],
        ),
      ),
    );
  }
}

这里涉及到ModalRoute.of方法,具体可以参看https://api.flutter.dev/flutter/widgets/ModalRoute/of.html

2)使用Navigator.push方法

// ProductDetailPagePush.dart
import 'package:flutter/material.dart';
import 'Model/ProductClass.dart';

class ProductDetailPage extends StatelessWidget {
  /* 接收参数 */
  final Product product;
  ProductDetailPage({Key key, @required this.product}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(product.name),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            Text(product.description),
            RaisedButton(
              child: Text('返回'),
              onPressed: () {
                Navigator.pop(context);
              },
            )
          ],
        ),
      ),
    );
  }
}

使用Navigator.push接收参数的重点在构造函数,通过在构造函数中接受参数进行传递

final Product product;
ProductDetailPage({Key key, @required this.product}) : super(key: key);

数据模型

// Model/ProductClass.dart
class Product {
  final String name;
  final String description;
  Product(this.name, this.description);
}
上一篇下一篇

猜你喜欢

热点阅读