上次只寫了方法和參數,此次寫了完整的示例,頁面間參數的傳遞和接收的示例。數據結構
一、參數傳遞
用在程序上解釋就是好比你進入一個商品選擇列表,當你想選擇一個商品的具體信息的時候,你就要傳遞商品編號,詳細頁面接受到編號後,顯示出不一樣的內容。app
聲明數據結構類
Dart中可使用類來抽象一個數據,好比咱們模仿一個商品信息,有商品標題和商品描述。咱們定義了一個Product類,裏邊有兩個字符型變量,title和description。less
- title:是商品標題。
- description: 商品詳情描述
class Product{ final String title; //商品標題 final String description; //商品描述 Product(this.title,this.description); }
構建一個商品列表
做一個商品的列表,這裏咱們採用動態的構造方法,在主方法裏傳遞一個商品列表(List)到自定義的Widget中。異步
先來看看主方法的編寫代碼:async
import 'package:flutter/material.dart'; void main(){ runApp(MaterialApp( title:'數據傳遞案例', home:ProductList( products:List.generate( 20, (i)=>Product('商品 $i','這是一個商品詳情,編號爲:$i') ), ) )); }
上面的代碼是主路口文件,主要是在home屬性中,咱們使用了ProductList,這個自定義組件,並且時候會報錯,由於咱們缺乏這個組件。這個組件咱們傳遞了一個products參數,也就是商品的列表數據,這個數據是咱們用List.generate
生成的。而且這個生成的List原型就是咱們剛開始定義的Product這個類(抽象數據)。ide
ProductList自定義組件的代碼:ui
class ProductList extends StatelessWidget{ final List<Product> products; ProductList({Key key,@required this.products}):super(key:key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title:Text('商品列表')), body:ListView.builder( itemCount:products.length, itemBuilder: (context,index){ return ListTile( title:Text(products[index].title), onTap:(){ } ); }, ) ); } }
先接受了主方法傳遞過來的參數,接受後用ListView.builder
方法,做了一個根據傳遞參數數據造成的動態列表。this
參數的傳遞
仍是使用Navigator
組件,而後使用路由MaterialPageRoute
傳遞參數,具體代碼以下。spa
Navigator.push( context, MaterialPageRoute( builder:(context)=>new ProductDetail(product:products[index]) ) );
子頁面接受參數並顯示
如今須要聲明ProductDetail
這個類(組件),先要做的就是接受參數,具體代碼以下。code
class ProductDetail extends StatelessWidget { final Product product; ProductDetail({Key key ,@required this.product}):super(key:key); @override Widget build(BuildContext context) { return new Scaffold( appBar: AppBar( title:Text('${product.title}'), ), body:Center(child: Text('${product.description}'),) ); } }
接受了參數,並把數據顯示在了頁面中。
完成代碼以下:
import 'package:flutter/material.dart'; //傳遞的數據結構,也能夠理解爲對商品數據的抽象 class Product{ final String title; //商品標題 final String description; //商品描述 Product(this.title,this.description); } void main(){ runApp(MaterialApp( title:'數據傳遞案例', home:ProductList( products:List.generate( 20, (i)=>Product('商品 $i','這是一個商品詳情,編號爲:$i') ), ) )); } class ProductList extends StatelessWidget{ final List<Product> products; ProductList({Key key,@required this.products}):super(key:key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title:Text('商品列表')), body:ListView.builder( itemCount:products.length, itemBuilder: (context,index){ return ListTile( title:Text(products[index].title), onTap:(){ Navigator.push( context, MaterialPageRoute( builder:(context)=>new ProductDetail(product:products[index]) ) ); } ); }, ) ); } } class ProductDetail extends StatelessWidget { final Product product; ProductDetail({Key key ,@required this.product}):super(key:key); @override Widget build(BuildContext context) { return new Scaffold( appBar: AppBar( title:Text('${product.title}'), ), body:Center(child: Text('${product.description}'),) ); } }
也能夠以下方式,效果是同樣的:
import 'package:flutter/material.dart'; class Product{//抽象類 final String title; //商品標題 final String description; //商品描述 Product(this.title,this.description); } class ProductList extends StatefulWidget{ //接收參數 final List<Product> products; ProductList({Key key,@required this.products}):super(key:key); @override State<StatefulWidget> createState() { return new ProductListState(); } } class ProductListState extends State<ProductList>{ final products = List.generate( 20, (i)=>Product('商品 $i','這是一個商品詳情,編號爲:$i') ); @override Widget build(BuildContext context) { return Scaffold( //能夠直接用return Scaffold() appBar: AppBar(title:Text('列表頁面')), body: ListView.builder( itemCount:products.length, itemBuilder: (context,index){ return ListTile( title:Text(products[index].title), onTap:(){ Navigator.push( context, MaterialPageRoute(builder:(context) => new ProductDetail(product: products[index]))); } ); }, ) ); } } class ProductDetail extends StatelessWidget{ final Product product; ProductDetail({Key key,@required this.product}):super(key:key); @override Widget build(BuildContext context){ return new Scaffold( appBar: AppBar( title:Text('${product.title}'), ), body:Center(child: Text('${product.description}'),) ); } }
二、頁面跳轉並返回數據
當咱們返回頁面時返回結果到上一個頁面(也就是父頁面)。這樣的場景常常用於,咱們去子頁面選擇了一項選項,而後把選擇的結果返回給父級頁面。
異步請求和等待
Dart中的異步請求和等待和ES6中的方法很像,直接使用async...await就能夠實現。好比下面做了一個找商品的方法,而後進行跳轉,注意這時候是異步的。等待結果回來以後,咱們再顯示出來內容。具體代碼以下:
_navigateToXiaoJieJie(BuildContext context) async{ //async是啓用異步方法 final result = await Navigator.push( //等待 context, MaterialPageRoute(builder: (context)=>ItemDetail()) ); //SnackBar是用戶操做後,顯示提示信息的一個控件,相似Tost,會自動隱藏。SnackBar是以Scaffold的showSnackBar方法來進行顯示的 Scaffold.of(context).showSnackBar(SnackBar(content:Text('$result'))); setState(() { showText= '$result'; }); }
SnackBar的使用
SnackBar
是用戶操做後,顯示提示信息的一個控件,相似Tost
,會自動隱藏。SnackBar
是以Scaffold
的showSnackBar
方法來進行顯示的。
Scaffold.of(context).showSnackBar(SnackBar(content:Text('$result')));
返回數據的方式
返回數據實際上是特別容易的,只要在返回時帶第二個參數就能夠了。
Navigator.pop(context,'xxxx'); //xxx就是返回的參數
我還加了一個showText,方便更好的看清楚效果。代碼以下:
import 'package:flutter/material.dart'; class ItemPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('要編號'),), body: Center( child: RouteButton(), ), ); } } class RouteButton extends StatefulWidget { _RouteButtonState createState() => _RouteButtonState(); } class _RouteButtonState extends State<RouteButton> { String showText = ''; @override Widget build(BuildContext context) { return Container( child: Column( children: <Widget>[ RaisedButton( onPressed: (){ _navigateToXiaoJieJie(context); }, child: Text('要編號'), ), Text(showText), ], ), ); } _navigateToXiaoJieJie(BuildContext context) async{ //async是啓用異步方法 final result = await Navigator.push( //等待 context, MaterialPageRoute(builder: (context)=>ItemDeetail()) ); //SnackBar是用戶操做後,顯示提示信息的一個控件,相似Tost,會自動隱藏。SnackBar是以Scaffold的showSnackBar方法來進行顯示的 Scaffold.of(context).showSnackBar(SnackBar(content:Text('$result'))); setState(() { showText= '$result'; }); } } class ItemDeetail extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('商品編號')), body: Center( child: Column( children: <Widget>[ RaisedButton( child: Text('1號商品'), onPressed: (){ Navigator.pop(context,'1號編號:123'); //第2個參數是返回的參數 }, ), RaisedButton( child: Text('2號商品'), onPressed: (){ Navigator.pop(context,'2號編號:456'); //返回的參數 }, ), ], ), ), ); } }