Flutter常用元件總結-頁面導航跳轉時資料的傳遞和返回
阿新 • • 發佈:2020-12-11
技術標籤:Flutter
一、頁面導航跳轉時資料的傳遞
通過構造方法傳遞頁面跳轉需要的資料:
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, //push跳轉頁面時,通過構造方法傳遞資料 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}'),) ); } }
執行效果圖,點選第6個商品item項:
二、頁面資料的返回
這裡先熟悉下Flutter的Toast元件SnackBar,它和Android的Toast元件很像,下面原始碼:
/// A lightweight message with an optional action which briefly displays at the /// bottom of the screen. /// 帶有可選操作的輕量級訊息,可在螢幕底部短暫顯示。 /// /// To display a snack bar, call `Scaffold.of(context).showSnackBar()`, passing /// an instance of [SnackBar] that describes the message. /// 通過描述訊息的[SnackBar]例項(Scaffold.of(context)獲取到的)。呼叫Scaffold.of(context).showSnackBar()顯示snack bar /// To control how long the [SnackBar] remains visible, specify a [duration]. /// 控制snack bar的顯示時間 /// A SnackBar with an action will not time out when TalkBack or VoiceOver are /// enabled. This is controlled by [AccessibilityFeatures.accessibleNavigation]. /// /// See also: /// /// * [Scaffold.of], to obtain the current [ScaffoldState], which manages the /// display and animation of snack bars. /// [Scaffold.of] 獲取當前的[ScaffoldState],管理snack bars的顯示和動畫. /// * [ScaffoldState.showSnackBar], which displays a [SnackBar]. /// * [ScaffoldState.removeCurrentSnackBar], which abruptly hides the currently /// displayed snack bar, if any, and allows the next to be displayed. /// * [SnackBarAction], which is used to specify an [action] button to show /// on the snack bar. /// * [SnackBarThemeData], to configure the default property values for /// [SnackBar] widgets. /// * <https://material.io/design/components/snackbars.html> class SnackBar extends StatefulWidget { /// Creates a snack bar. /// /// The [content] argument must be non-null. The [elevation] must be null or /// non-negative. const SnackBar({ Key key, @required this.content, this.backgroundColor, this.elevation, this.shape, this.behavior, this.action, this.duration = _snackBarDisplayDuration, this.animation, this.onVisible, }) : assert(elevation == null || elevation >= 0.0), assert(content != null), assert(duration != null), super(key: key); /// The primary content of the snack bar. /// /// Typically a [Text] widget. final Widget content; /// The Snackbar's background color. If not specified it will use /// [ThemeData.snackBarTheme.backgroundColor]. If that is not specified /// it will default to a dark variation of [ColorScheme.surface] for light /// themes, or [ColorScheme.onSurface] for dark themes. final Color backgroundColor; /// The z-coordinate at which to place the snack bar. This controls the size /// of the shadow below the snack bar. /// /// Defines the card's [Material.elevation]. /// /// If this property is null, then [ThemeData.snackBarTheme.elevation] is /// used, if that is also null, the default value is 6.0. final double elevation; /// The shape of the snack bar's [Material]. /// /// Defines the snack bar's [Material.shape]. /// /// If this property is null then [ThemeData.snackBarTheme.shape] is used. /// If that's null then the shape will depend on the [SnackBarBehavior]. For /// [SnackBarBehavior.fixed], no overriding shape is specified, so the /// [SnackBar] is rectangular. For [SnackBarBehavior.floating], it uses a /// [RoundedRectangleBorder] with a circular corner radius of 4.0. final ShapeBorder shape; /// This defines the behavior and location of the snack bar. /// /// Defines where a [SnackBar] should appear within a [Scaffold] and how its /// location should be adjusted when the scaffold also includes a /// [FloatingActionButton] or a [BottomNavigationBar] /// /// If this property is null, then [ThemeData.snackBarTheme.behavior] /// is used. If that is null, then the default is [SnackBarBehavior.fixed]. final SnackBarBehavior behavior; /// (optional) An action that the user can take based on the snack bar. /// /// For example, the snack bar might let the user undo the operation that /// prompted the snackbar. Snack bars can have at most one action. /// /// The action should not be "dismiss" or "cancel". final SnackBarAction action; /// The amount of time the snack bar should be displayed. /// /// Defaults to 4.0s. /// /// See also: /// /// * [ScaffoldState.removeCurrentSnackBar], which abruptly hides the /// currently displayed snack bar, if any, and allows the next to be /// displayed. /// * <https://material.io/design/components/snackbars.html> final Duration duration; /// The animation driving the entrance and exit of the snack bar. final Animation<double> animation; /// Called the first time that the snackbar is visible within a [Scaffold]. final VoidCallback onVisible; // API for Scaffold.showSnackBar(): /// Creates an animation controller useful for driving a snack bar's entrance and exit animation. static AnimationController createAnimationController({ @required TickerProvider vsync }) { return AnimationController( duration: _snackBarTransitionDuration, debugLabel: 'SnackBar', vsync: vsync, ); } /// Creates a copy of this snack bar but with the animation replaced with the given animation. /// /// If the original snack bar lacks a key, the newly created snack bar will /// use the given fallback key. SnackBar withAnimation(Animation<double> newAnimation, { Key fallbackKey }) { return SnackBar( key: key ?? fallbackKey, content: content, backgroundColor: backgroundColor, elevation: elevation, shape: shape, behavior: behavior, action: action, duration: duration, animation: newAnimation, onVisible: onVisible, ); } @override State<SnackBar> createState() => _SnackBarState(); }
知識點1:SnackBar
是使用者操作後,顯示提示資訊的一個控制元件,類似Android中的Toast
,會自動隱藏。SnackBar
是以Scaffold
的showSnackBar
方法來進行顯示的。
Scaffold.of(context).showSnackBar(SnackBar(content:Text('$result')));
返回資料的方式
知識點2:返回資料其實是特別容易的,通過路由導航方法Navigator.pop()的第二個引數進行傳遞即可,只要在返回時帶第二個引數就可以了。
Navigator.pop(context,'xxxx'); //xxx就是返回的引數
示例:
import 'package:flutter/material.dart'; void main(){ runApp(MaterialApp( title:'頁面跳轉返回資料', home:FirstPage() )); } class FirstPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar:AppBar(title:Text("足沐春風")), body:Center( child: RouteButton(), ) ); } } //跳轉的Button class RouteButton extends StatelessWidget { @override Widget build(BuildContext context) { return RaisedButton( onPressed:(){ _navigateToServiceMaster(context); }, child: Text('請選擇技師'), ); } //知識點3:使用非同步等待關鍵詞async、await _navigateToServiceMaster(BuildContext context) async{ //async是啟用非同步方法 final result = await Navigator.push(//等待 context, MaterialPageRoute(builder: (context)=> ServiceMaster()) ); //知識點1:在首頁Toast彈訊息,獲取上一頁面返回來的訊息 Scaffold.of(context).showSnackBar(SnackBar(content:Text('$result'))); } } class ServiceMaster extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar:AppBar( title:Text('技師榮譽榜') ), body:Center( child:Column( children: <Widget>[ RaisedButton( child: Text('1號 國家級技師'), onPressed: (){ //知識點2:pop返回到首頁,並攜帶字元引數資料 "服務於世界各國領導人,譽滿全球。" 返回到首頁 Navigator.pop(context,'服務於世界各國領導人,譽滿全球。'); }, ) ,RaisedButton( child: Text('2號 宗師級技師'), onPressed: (){ //知識點2:pop返回到首頁,並攜帶字元引數資料 "服務於江湖各界英雄人物。" 返回到首頁 Navigator.pop(context,'服務於江湖各界英雄人物。'); }, ) , RaisedButton( child: Text('3號 業界知名技師'), onPressed: (){ //知識點2:pop返回到首頁,並攜帶字元引數資料 "服務於藝術界、商界風雲人物。" 返回到首頁 Navigator.pop(context,'服務於藝術界、商界風雲人物。'); }, ) , ], ) ) , ); } }
當進入技師列表點選3號技師按鈕時,會從當前所處的第二個頁面pop返回主介面,並彈出一個Toast訊息:SnackBar訊息,圖如下: