flutter學習總結(語法,組件,佈局,和路由)

一.helloworld應用

按國際慣例,寫來一個hello world應用跑一遍.

創建項目

啓動 VS Code
調用 View>Command Palette…
輸入 ‘flutter’, 然後選擇 ‘Flutter: New Project’ action
輸入 Project 名稱 (如myapp), 然後按回車鍵
指定放置項目的位置,然後按藍色的確定按鈕
等待項目創建繼續,並顯示main.dart文件
開始代碼,寫在根目錄\lib\main.dart文件中,這就是Flutter主文件.

基本思路:

引入flutter包

入口函數

聲明MyApp類

重寫build方法,它返回一個MaterialApp風格的組件

在Material組件的home屬性裏賦值一個Scaffold組件

在Scaffold組件裏創建appBar和body

在body的中間區域添加hello world文本

填充代碼:

// flutter相當於一個UI庫,所以使用前要引入flutter
import 'package:flutter/material.dart';

// 入口函數
void main() => runApp(MyApp());

// 聲明MyApp類
class MyApp extends StatelessWidget {
// 重寫build方法,它返回一個Material風格的組件
  @override
  Widget build(BuildContext context) {
// 在MaterialApp組件的home屬性裏賦值一個Scaffold組件
    return MaterialApp(
      title: "welcome",
      home: Scaffold(
// 在Scaffold組件(相當於腳手架的東西)裏創建appBar和body
        appBar: AppBar(title: Text('This is header')),
// 在body的中間區域添加hello world文本
        body: Center(child: Text('hello world')),
      ),
      debugShowCheckedModeBanner: false,//去掉右上方的bug
    );
  }
}

效果:在這裏插入圖片描述
精簡版基本模板:

import 'package:flutter/material.dart';
void main()=>runApp(MyApp());
class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return MaterialApp(
      title:'test',
      home:Scaffold(
        appBar: new AppBar(
          title:new Text("這是頭部"),
          
        ),
        body:new Text('內容')
      )
    );
  }
}

也許你對上面的語法還不夠了解,但你不必驚慌,我會進行說明,那先來看一下Dart中的函數。

Dart語法Function函數

Dart是面向對象的語言,即使是函數也是對象,並且屬於函數類型的對象。
比如我們寫的上面第二行代碼,就是一個函數

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

上面是簡寫,普通寫法如下:

void main() {
  return runApp(MyApp());
}

總結:發現Dart語言是不能省略結束符“;”的。

二.常用組件

Text()組件介紹

這個是文本組件,是非常常見的.記住在flutter中一切東西都是組件(組件英文名叫widget).

Text()組件的屬性介紹:

textAlign文字對齊屬性
center: 文本以居中形式對齊,這個也算比較常用的了。
left:左對齊,經常使用,讓文本居左進行對齊,效果和start一樣。
right :右對齊,使用頻率也不算高。
start:以開始位置進行對齊,類似於左對齊。
end: 以爲本結尾處進行對齊,不常用。有點類似右對齊.

總結起來,也就算三個對齊方式,left(左對齊)、center(居中對齊)、right(右對齊)。我們來看一下具體代碼寫法:
在這裏插入圖片描述
內容寫在第一個參數裏,屬性以對象值的方式寫.

maxLines屬性最多顯示的行數

maxLines屬性設置顯示的行數,比如我們給1,文字只能顯示出1行了,多的自動消失.

overflow超出顯示屬性

有三個值:
clip:直接切斷,
ellipsis:後面顯示三個省略號,
fade:直接切斷,並帶有整行上下漸變的效果.
在這裏插入圖片描述
注意值的寫法是要加上Text,用TextOverflow點出各自的值.

style屬性

style屬性內容比較多:

inherit 是否將null值替換爲祖先文本樣式中的值(例如,在TextSpan樹中)。如果爲false,則沒有顯式值的屬性將恢復爲默認值:白色,字體大小爲10像素,採用無襯線字體。
color 字體的顏色
fontSize 文字大小,單位爲像素,如果沒有指定大小則默認爲14像素,可以乘以textScaleFactor來增加字體大小以便用戶更加方便的閱讀
fontWeight 字體厚度,可以使文本變粗或變細
fontStyle 字體變形,有兩種 FontStyle.normal(字體直立), FontStyle.italic(字體傾斜)
letterSpacing 字母間距,整數拉開字母距離,若是負數則拉近字母距離
wordSpacing,單詞間距,同上
textBaseline 用於對齊文本的水平線
height 文本行高,爲字體大小的倍數
locale 用於選擇區域特定符號的區域設置
background 文本的背景顏色
shadows 文本的陰影可以利用列表疊加處理,例如shadows: [Shadow(color:Colors.black,offset: Offset(6, 3), blurRadius: 10)], color即陰影的顏色, offset即陰影相對文本的偏移座標,blurRadius即陰影的模糊程度,越小越清晰
decoration 文字的線性裝飾,比如 underline 下劃線, lineThrough刪除線
decorationColor 文本裝飾線的顏色
decorationStyle 文本裝飾線的樣式,比如 dashed 虛線
debugLabel 這種文本樣式的可讀描述,此屬性僅在調試構建中維護。

具體的可以看官網:https://api.flutter.dev/flutter/painting/TextStyle-class.html#painting.TextStyle.1

小技巧快速打開虛擬機的方法:依次點擊下面的即可
在這裏插入圖片描述

Container組件的使用

Container組件相當於我們的div標籤,它的作用就是方便我們進行佈局的.

alignment屬性

alignment屬性的作用是針對的是Container內child的對齊方式,也就是容器子內容的對齊方式,並不是容器本身的對齊方式.
在這裏插入圖片描述
常用屬性有:

bottomCenter:下部居中對齊。
botomLeft: 下部左對齊。
bottomRight:下部右對齊。
center:縱橫雙向居中對齊。
centerLeft:縱向居中橫向居左對齊。
centerRight:縱向居中橫向居右對齊。
topLeft:頂部左側對齊。
topCenter:頂部居中對齊。
topRight: 頂部居左對齊。

總結規律:縱向在前,橫向在後.

寬width,高height,背景顏色color(注意color不是字體顏色,而是背景顏色)設置

在這裏插入圖片描述

padding和margin屬性

跟我們的css樣式一樣,但注意點寫法:值是要帶常量聲明

padding:const EdgeInsets.all(20.0)

這句的意思是設置Container的內邊距是20,左右上下全部爲20,這看起來非常容易。那我們再加大一點難度。如果上邊距爲30,左邊距爲10,這時候EdgeInsets.all()就滿足不了我們了。
我們用EdgeInsets.fromLTRB(value1,value2,value3,value4) 可以滿足我們的需求,LTRB分別代表左、上、右、下。

decoration修飾屬性

背景設置:
decoration屬性主要是用來設置背景和邊框.
比如我們要設置漸變背景,上面的color背景只能設置單一顏色,我們可以用decoration來設置(與color不能同時存在,只能留一個)
設置方法:這時候就要用new BoxDecoration()這個組件.寫法如下:
在這裏插入圖片描述
邊框設置:(這個不需要new)

border:Border.all(width:2.0,color:Colors.purple)

效果:
在這裏插入圖片描述
附完整代碼:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return MaterialApp(
      title:"hello widget",
      home:Scaffold(
        body:Center(
          child:Container(
            child:new Text('hahahahahahahahahahahahahhahahahahahahahahahahahahhahahahahahahahahahahahahhahahahahahahahahahahahahhahahahahahahahahahahahah',
            style:TextStyle(
              fontSize:20.0
            )
            ),
            alignment:Alignment.topLeft,
            width:500.0,
            height: 400.0,
            
            padding:const EdgeInsets.all(20.0),
            margin:const EdgeInsets.all(30.0),
            decoration:new BoxDecoration(
                  gradient:const LinearGradient(
                    colors:[Colors.lightBlue,Colors.greenAccent,Colors.purple]
                  ),
                  border:Border.all(width:5.0,color:Colors.purple)
                )
           

          )
        )
      )
    );
  }
}

遇到的坑點:記住color背景屬性和decoration屬性不能同時存在,存在會報錯.

Image圖片組件

圖片引入的幾種方式:
Image.asset:加載資源圖片,就是加載項目資源目錄中的圖片,加入圖片後會增大打包的包體體積,用的是相對路徑。
Image.network:網絡資源圖片,意思就是你需要加入一段http://xxxx.xxx的這樣的網絡路徑地址。
Image.file:加載本地圖片,就是加載本地文件中的圖片,這個是一個絕對路徑,跟包體無關。
Image.memory: 加載Uint8List資源圖片(相當於內存一樣),這個我目前用的不是很多.
圖片fit填充屬性的設置

填充屬性值有以下幾種:

BoxFit.fill:全圖顯示,圖片會被拉伸,並充滿父容器。

BoxFit.contain:全圖顯示,顯示原比例,可能會有空隙。

BoxFit.cover:顯示可能拉伸,可能裁切,充滿(圖片要充滿整個容器,還不變形)。

BoxFit.fitWidth:寬度充滿(橫向充滿),顯示可能拉伸,可能裁切。

BoxFit.fitHeight :高度充滿(豎向充滿),顯示可能拉伸,可能裁切。

BoxFit.scaleDown:效果和contain差不多,但是此屬性不允許顯示超過源圖片大小,可小不可大。
圖片的背景顏色混合模式設置

color:是要混合的顏色,如果你只設置color是沒有意義的。
colorBlendMode:是混合模式,相當於我們如何混合

圖片混合模式(colorBlendMode)和color屬性配合使用,能讓圖片改變顏色,裏邊的模式非常的多,產生的效果也是非常豐富的。
效果:
在這裏插入圖片描述

repeat圖片重複屬性

ImageRepeat.repeat : 橫向和縱向都進行重複,直到鋪滿整個畫布。

ImageRepeat.repeatX: 橫向重複,縱向不重複。

ImageRepeat.repeatY:縱向重複,橫向不重複。
在這裏插入圖片描述

ListView列表循環組件

下面我們使用了ListView,然後在他的內部children中,使用了widget數組,因爲是一個列表,所以它接受一個數組,然後有使用了listTite組件(列表瓦片),在組件中放置了圖標和文字。
在這裏插入圖片描述
上面默認就是縱向列表,怎樣變爲橫向列表你,在ListView組件裏,設置scorllDirectin屬性值爲Axis.horizontal即可.
在這裏插入圖片描述
上面內容不能寫死,怎樣使用動態列表呢?
用dart語言準備數組,數組的聲明方式有以下幾種方式:

var myList = List(): 非固定長度的聲明。
var myList = List(2): 固定長度的聲明。
var myList= List<String>():固定類型的聲明方式。
var myList = [1,2,3]: 對List直接賦值。

我聲明和接收如下
在這裏插入圖片描述
使用後顯示如下:
在這裏插入圖片描述

GridView網格列表組件

// 網格佈局的基本使用

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'GridView',
        home: Scaffold(
            body: GridView.count(
          padding: const EdgeInsets.all(20.0),
          crossAxisSpacing: 10.0,
          crossAxisCount: 3, //每行顯示的列數
          children: <Widget>[
            Icon(Icons.ac_unit),
            Icon(Icons.airport_shuttle),
            Icon(Icons.all_inclusive),
            Icon(Icons.beach_access),
            Icon(Icons.cake),
            Icon(Icons.free_breakfast)
          ],
        )));
  }
}

常用屬性:

padding:表示內邊距,這個應該很熟悉。
crossAxisSpacing:網格間的空當,相當於每個網格之間的間距。
crossAxisCount:網格的列數,相當於一行放置的網格數量。

GridView用來圖片佈局:
注意第一個gridDelegate屬性,它有兩個參數,如下所示,第一個表示以數量佈局,第二個表示以內容佈局.
在這裏插入圖片描述
具體使用如下:

//圖片佈局
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'GridView',
        home: Scaffold(
            body: GridView(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3,
              mainAxisSpacing: 2.0,
              crossAxisSpacing: 2.0,
              childAspectRatio: 0.7),
          children: <Widget>[
            new Image.network(
                'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2571762536.webp'),
            new Image.network(
                'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2571762536.webp'),
            new Image.network(
                'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2571762536.webp'),
            new Image.network(
                'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2571762536.webp'),
            new Image.network(
                'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2571762536.webp'),
            new Image.network(
                'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2571762536.webp'),
            new Image.network(
                'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2571762536.webp'),
            new Image.network(
                'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2571762536.webp'),
            new Image.network(
                'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2567998580.webp'),
            new Image.network(
                'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2567998580.webp'),
            new Image.network(
                'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2567998580.webp'),
          ],
        )));
  }
}

效果:
在這裏插入圖片描述

說明:
childAspectRatio:是寬高比,這個值的意思是寬是高的多少倍,如果寬是高的2倍,那我們就寫2.0,如果高是寬的2倍,我們就寫0.5。

三.佈局

水平佈局Row的使用

Row控件就是水平控件,它可以讓Row裏邊的子元素進行水平排列,Row控件可以分爲不靈活排列和靈活排列兩種.

不靈活排列(默認)

從字面上就可以理解到,不靈活就是根據Row子元素內容的大小,進行佈局。如果子元素內容不足,它會留有空隙,如果子元素內容超出,它會警告.

import 'package:flutter/material.dart';
void main(){
  runApp(MyApp());
}

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return MaterialApp(
      title:"Row佈局",
      home:Scaffold(
        appBar: AppBar(title:Text('頭部')),
        body:Row(
          children:<Widget>[
            RaisedButton(
              child:Text('藍色按鈕'),
              color:Colors.lightBlue,
              onPressed:(){}
            ),
            RaisedButton(
              child:Text('紅色按鈕'),
              color:Colors.redAccent,
              onPressed:(){}
            ),
            RaisedButton(
              child:Text('黃色按鈕黃色按鈕黃色按鈕黃色按鈕黃色按鈕黃色按鈕'),//文字超出會警告
              color:Colors.orangeAccent,
              onPressed: (){},
            )
          ]
        )
      )
    );
  }
}

小坑:如果按鈕不寫onPressed屬性,背景顏色不會出來.
效果:
在這裏插入圖片描述
假設上面"黃色按鈕""只留四個字,那會出現下面沒有充滿的情況,
在這裏插入圖片描述
怎麼讓它剛好充滿呢,這就用到我們的靈活佈局了.

靈活佈局

靈活佈局只要在按鈕的外邊加入Expanded就可以,它會自動填充一屏.

import 'package:flutter/material.dart';
void main(){
  runApp(MyApp());
}

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return MaterialApp(
      title:'切換文字',
      home:Scaffold(
        appBar:AppBar(title:Text("靈活水平佈局")),
        body:Row(
          children: <Widget>[
            RaisedButton(
              child: Text("藍色按鈕"),
              color:Colors.lightBlue,
              onPressed: (){},
            ),
            Expanded(
              child:RaisedButton(
                child:Text('紅色按鈕'),
                color:Colors.redAccent,
                onPressed: (){},
              )
            ),
            Expanded(
              child:RaisedButton(
                child:Text('黃色按鈕'),
                onPressed:(){},
                color:Colors.orangeAccent
              )
            )
          ],
        )

      )
    );
  }
}

在這裏插入圖片描述
靈活水平佈局和不靈活水平佈局可以互相結合使用.

Column垂直佈局的使用

// 垂直佈局

import 'package:flutter/material.dart';
void main (){
  runApp(MyApp());
}

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return MaterialApp(
      title:'',
      home:Scaffold(
        appBar:AppBar(title:Text('垂直佈局')),
        body:Column(
          mainAxisAlignment:MainAxisAlignment.center,//主軸
          crossAxisAlignment: CrossAxisAlignment.start,//副軸
          children: <Widget>[
            Text('第一行第一行第一行'),
           Expanded(
             child: Text('第二行'),//這裏自適應
           ) ,
            Text('第三行第三行第三行第三行第三行第三行第三行')
          ],
        )
      )
    );
  }
}

在這裏插入圖片描述

Stack,Positioned層疊佈局的使用

水平佈局和垂直佈局確實很好用,但是有一種情況是無法完成的,比如放入一個圖片,圖片上再寫一些字或者放入容器,這時候Row和Column就力不從心了。Flutter爲這種情況準備了Stack層疊佈局.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: '',
        home: Scaffold(
            appBar: AppBar(
              title: Text("Stack層疊佈局"),
            ),
            body: Center(
                child: new Stack(
              alignment: const FractionalOffset(0.5, 0.8),
              children: <Widget>[
                new CircleAvatar(
                  backgroundImage: new NetworkImage(
                      'https://avatars1.githubusercontent.com/u/45531884?s=460&v=4'),
                  radius: 100.0,
                ),
                new Container(
                    decoration: new BoxDecoration(color: Colors.lightBlue),
                    padding: EdgeInsets.all(5.0),
                    child: new Text('我是層疊文本'))
              ],
            ))));
  }
}

在這裏插入圖片描述
alignment屬性:是控制層疊的位置的,建議在兩個內容進行層疊時使用。它有兩個值X軸距離和Y軸距離,值是從0到1的,都是從上層容器的左上角開始算起的。

CircleAvatar頭像組件:這個經常用來做頭像,組件裏邊有個radius的值可以設置圖片的弧度。

Stack層疊的Position屬性

當背景上層疊的組件超過兩個時,我們可以考慮用Position定位屬性,層疊定位無需alignment屬性,直接給定位設置對應定位的座標即可,操作如下:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: '',
        home: Scaffold(
            appBar: AppBar(
              title: Text("Stack層疊佈局"),
            ),
            body: Center(
                child: new Stack(children: <Widget>[
              new CircleAvatar(
                  backgroundImage: new NetworkImage(
                      'https://avatars1.githubusercontent.com/u/45531884?s=460&v=4'),
                      radius: 100.0,
                      ),
              new Positioned(
                top:10.0,
                left:40.0,
                child:Text('定位內容1')
              ),
              new Positioned(
                right: 50.0,
                bottom: 20.0,
                child:Text('定位內容2')
              )
            ]))));
  }
}

在這裏插入圖片描述
Positioned組件的位置屬性

bottom: 距離層疊組件下邊的距離
left:距離層疊組件左邊的距離
top:距離層疊組件上邊的距離
right:距離層疊組件右邊的距離
width: 層疊定位組件的寬度
height: 層疊定位組件的高度

Card卡片組件佈局

這個佈局可以做出很炫的東西,比如我們現在要開發一個類似收穫地址的列表,並且列表外部使用一個卡片式佈局,代碼如下:

// 卡片佈局
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: '',
        home: Scaffold(
            appBar: AppBar(title: Text('card佈局')),
            body: Center(
                child: new Card(
              child: Column(
                //定義垂直佈局
                children: <Widget>[
                  ListTile(//每個瓦片
                      title: Text("廣東省深圳市龍華區",
                          style: TextStyle(fontWeight: FontWeight.w600)), //標題
                      subtitle: Text('電話:13800138000'), //第二行標題
                      leading: Icon(Icons.account_box, color: Colors.red) //左邊內容
                      ) ,
                      new Divider(),//增加邊框
                    ListTile(
                      title:Text("廣東省深圳市龍華區廣東省深圳市龍華區",style:TextStyle(fontWeight:FontWeight.w600)),
                      subtitle: Text('電話:13800138000'),
                      leading:Icon(Icons.add_location,color:Colors.lightBlue)
                    ),
                    new Divider(color:Colors.red),
                    ListTile(
                      title:Text("廣東省深圳市龍華區廣東省深圳市龍華區",style:TextStyle(fontWeight:FontWeight.w600)),
                      subtitle: Text('電話:13800138000'),
                      leading:Icon(Icons.add_location,color:Colors.lightBlue)
                    ),
                    new Divider(color:Colors.blue)
                ],
              ),
            ))));
  }
}

在這裏插入圖片描述

四.路由導航

1.頁面跳轉的應用:

導航的使用在任何程序裏都至關重要,這也是一個程序的靈魂.下面先來一個一般頁面的導航和返回,代碼如下:

import 'package:flutter/material.dart';

void main(){
 runApp(
   MaterialApp(
     title:'路由導航',
     home:new FirstScreen()
   )
 );
}

class FirstScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return Scaffold(
      appBar:AppBar(title:Text('點擊下面跳轉查看詳情頁面')),
      body:Center(
        child: new RaisedButton(
          child:Text("去詳情頁面"),
          onPressed:(){
            Navigator.push(context,
            MaterialPageRoute(builder:(context){
              return SecondScreen();
            })
            );
          }
        ),
      )

    );
  }
}

class SecondScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return MaterialApp(
      home:Scaffold(
        appBar: AppBar(title:Text("這是詳情頁")),
        body:Center(
          child:
          RaisedButton(
            child:Text('返回上一頁'),
            onPressed:(){
              Navigator.pop(context);//返回上一頁,直接調用pop方法,把上下文傳過去即可
            }
          )
        )
      )
    );
  }
}

路由的Navigator.push()和Navigator.pop()方法說明:
Navigator.push():是跳轉到下一個頁面,它接收兩個參數,參數1是上下文,參數2是MaterialPageRoute()組件,裏面有一個builder屬性,值是一個函數,參數是上下文,內容是要跳轉的頁面組件即可.
實現效果:
在這裏插入圖片描述

2.頁面跳轉的參數傳遞

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(50,(index)=>
        Product('商品$index','這是商品詳情,編號爲$index')
      ),
    )
  ));
}


class ProductList extends StatelessWidget{
  
  final List<Product> products;// 引入上面的數組
  ProductList({Key key,@required this.products}):super(key:key);//掛載在當前組件上,除了this.products,其它是固定寫法
  @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)=>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 Scaffold(
      appBar: AppBar(title:Text(product.title)),
      body:Center(child: Text(product.description),)
    );
  }
}

說明:在點擊商品列表的時候,我們用product屬性將裏面的products(商品信息,裏面有標題和描述)傳遞了出去,在ProductDetail頁面組件中進行了接收和使用.

實現效果:
在這裏插入圖片描述

3.返回頁面攜帶參數
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()));
  }

}

class RouteButton extends StatelessWidget{
  @override 
  Widget build(BuildContext context){
    return RaisedButton(
          child: Text('去找小姐姐'),
          onPressed: () {
            //下面這裏調用異步請求,把上下文傳遞過去
            _navigateToXiaoJieJie(context);
          },
        );
  }
   //在組件裏準備異步請求函數,裏面也是兩個上下文方法,大括號前記得寫async
  _navigateToXiaoJieJie(BuildContext context) async {
    final result = await Navigator.push(
        context, MaterialPageRoute(builder: (context) => XiaoJieJie()));
    //返回後的數據顯示
    Scaffold.of(context).showSnackBar(SnackBar(
      content: Text('$result'),
    ));
  }
}

 

class XiaoJieJie extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("請選擇你要的小姐姐")),
        body: Center(
            child: Column(
          children: <Widget>[
            RaisedButton(
              child: Text("大長腿小姐姐"),
              onPressed: () {
                Navigator.pop(context, "大長腿電話:1511008888");
              },
            ),
            RaisedButton(
              child: Text("小長腿小姐姐"),
              onPressed: () {
                Navigator.pop(context, "小長腿電話:1511009999");
              },
            ),
          ],
        )));
  }
}

效果:
在這裏插入圖片描述
最後,附上源碼鏈接地址:[email protected]:huanggengzhong/flutter.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章