Flutter框架概覽

Flutter框架概覽

Flutter是什么

  • 是一款移動(dòng)應(yīng)用程序SDK吊圾,一份代碼可以同時(shí)生成ios和Android兩個(gè)高性能闷愤、高保真的應(yīng)用程序
  • 目標(biāo)是使開(kāi)發(fā)人員能夠交付在不同平臺(tái)上都感覺(jué)自然流暢的高性能應(yīng)用程序。我們兼容滾動(dòng)行為丙猬,排版,圖標(biāo)等方面的差異

Flutter優(yōu)勢(shì)

  • 跨平臺(tái):至少可以跨4種平臺(tái),甚至支持嵌入式開(kāi)發(fā)肿轨,常用的有(Linux,Android蕊程,IOS椒袍,甚至可以在谷歌最新的操作系統(tǒng)上Fuchsia進(jìn)行運(yùn)行),經(jīng)過(guò)第三方擴(kuò)展藻茂,甚至可以跑在MacOS和Windows上驹暑。Flutter算是支持平臺(tái)最多的框架,良好的跨平臺(tái)性辨赐,減少開(kāi)發(fā)成本
  • 原生用戶界面:它是原生的优俘,體驗(yàn)好,性能好
  • 開(kāi)源免費(fèi)

主流框架的對(duì)比

  • Cordova:Cordova基于網(wǎng)頁(yè)技術(shù)進(jìn)行包裝掀序,利用插件的形式開(kāi)發(fā)移動(dòng)應(yīng)用
  • RN(React Native):RN的效率由于是將View編譯成了原生View帆焕,所以效率上要比基于Cordova的HTML5高很多,但是它也有效率問(wèn)題不恭,RN的渲染機(jī)制是基于前端框架的考慮叶雹,復(fù)雜的UI渲染是需要依賴多個(gè)view疊加,RN的列表方案不友好
  • Flutter:在渲染技術(shù)上换吧,選擇了自己實(shí)現(xiàn)(GDI)折晦,有更好的可控性,使用了新的語(yǔ)言Dart沾瓦,避免了RN的那種通過(guò)橋接器與Javascript通訊導(dǎo)致效率底下的問(wèn)題满着,所以性能方面比RN更高一籌;

120fps超高性能

Flutter采用GPU渲染技術(shù)暴拄,所以性能極高

Flutter編寫的應(yīng)用是可以達(dá)到120fps(每秒傳輸幀數(shù)),完全可以勝任游戲的制作漓滔,RN的性能只能達(dá)到60fps。

核心原則

Flutter包括一個(gè)現(xiàn)代的響應(yīng)式框架乖篷,一個(gè)2D渲染引擎响驴,現(xiàn)成的widget和開(kāi)發(fā)工具

Dart語(yǔ)法Function函數(shù)

Dart是面向?qū)ο蟮恼Z(yǔ)言,即使是函數(shù)也是對(duì)象撕蔼,并且屬于Function類型的對(duì)象豁鲤,這意味著函數(shù)可以分配給變量或作為參數(shù)傳遞給其他函數(shù)

Dart是一切皆對(duì)象秽誊,包括數(shù)字和函數(shù)

StatefulWidget和StatelessWidget

  • StatefulWidget:具有可變狀態(tài)的窗口部件,也就是你在使用應(yīng)用的時(shí)候就可以隨時(shí)變化琳骡,如果常見(jiàn)的進(jìn)度條锅论,隨著進(jìn)度不斷變化
  • StatelessWidge:不可變狀態(tài)窗口部件,也就是你在使用時(shí)不可以改變楣号,如果固定的文字

flutter的基本代碼

import 'package:flutter/material.dart';
//主函數(shù)(入口函數(shù))最易,下面我會(huì)簡(jiǎn)單說(shuō)說(shuō)Dart的函數(shù)
void main() =>runApp(MyApp());
// 聲明MyApp類
class MyApp extends StatelessWidget{
  //重寫build方法
  @override
  Widget build(BuildContext context){
    //返回一個(gè)Material風(fēng)格的組件
   return MaterialApp(
      title:'Welcome to Flutteraa',
      home:Scaffold(
        //創(chuàng)建一個(gè)Bar,并添加文本
        appBar:AppBar(
          title:Text('Welcome to Flutter'),
        ),
        //在主體的中間區(qū)域炫狱,添加一個(gè)hello world 的文本
        body:Center(
          child:Text(
            'Hello JSPang  ,非常喜歡前端藻懒,并且愿意為此奮斗一生。我希望可以出1000集免費(fèi)教程视译。',
  textAlign:TextAlign.left,
  overflow:TextOverflow.ellipsis,
  maxLines: 1,
  style: TextStyle(
    fontSize:25.0,
    color:Color.fromARGB(255, 255, 150, 150),
    decoration:TextDecoration.underline,
    decorationStyle:TextDecorationStyle.solid,
  ),
          ),
        ),
      ),
    );
  }
}

常用組件

Container容器組件的使用

Alignment屬性:這個(gè)屬性針對(duì)的是Container內(nèi)child的對(duì)齊方式嬉荆,也就是容器子內(nèi)容的對(duì)齊方式,并不是容器本身的對(duì)齊方式

child:Container(
             child:new Text('Hello JSPang',style: TextStyle(fontSize: 40.0),),
             alignment: Alignment.center,
           ),
  • bottomCenter:下部居中對(duì)齊
  • bottomLeft:下部左對(duì)齊
  • bottomRight:下部右對(duì)齊
  • center:縱橫雙向居中對(duì)齊
  • centerLeft:縱向居中橫向居左對(duì)齊
  • centerRight:縱向居中橫向居右對(duì)齊
  • topLeft:頂部左側(cè)對(duì)齊
  • topCenter:頂部居中對(duì)齊
  • topRight:頂部居左對(duì)齊

設(shè)置寬酷含,高和顏色屬性

設(shè)置寬鄙早,高和顏色屬性只要在屬性名稱后加入浮點(diǎn)型數(shù)字就可以

child:Container(
  child:new Text('Hello JSPang',style: TextStyle(fontSize: 40.0),),
  alignment: Alignment.center,
  width:500.0,
  height:400.0,
  color: Colors.lightBlue,
),

padding,margin椅亚,decoration


padding

padding:const EdgeInsets.all(10.0),
padding:const EdgeInsets.fromLTRB(value1,value2,value3,value4)
// 我們用EdgeInsets.fromLTRB(value1,value2,value3,value4) 可以滿足我們的需求限番,LTRB分別代表左、上什往、右扳缕、下。

margin

// margin是container和外部元素的距離
 margin: const EdgeInsets.all(10.0),
 margin:const EdgeInsets.fromLTRB(value1,value2,value3,value4)

decoration

// decoration是container的修飾器别威,主要的功能是設(shè)置背景和邊框
// 如果要給背景加入一個(gè)漸變躯舔,需要使用BoxDecoration這個(gè)類,(注意省古,如果設(shè)置了decoration粥庄,就不要再設(shè)置color屬性了,會(huì)沖突)
decoration: BoxDecoration(
        gradient: const LinearGradient(colors: [Colors.lightBlue,Colors.greenAccent,Colors.purple] )),


border

border:Border.all(width:2.0,color:Colors.red)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter 學(xué)習(xí)',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Iris'),
        ),
        body: Center(
          child: Container(
            child: new Text('世界那么大豺妓,我想去看看',style: TextStyle(fontSize: 20.0),),
            alignment: Alignment.center,
            width: 500.0,
            height: 400.0,
            padding: const EdgeInsets.fromLTRB(10.0, 30.0, 0.0, 0.0),
            margin: const EdgeInsets.all(10.0),
            decoration: BoxDecoration(
              gradient: const LinearGradient(
                colors: [Colors.lightBlue,Colors.greenAccent,Colors.purple]
              ),
              border: Border.all(width: 1.0,color: Colors.red)
            ),
          ),
        ),
      ),
    );
  }
}

加入圖片的幾種方式

  • Image.asset:加載資源圖片惜互,就是加載項(xiàng)目資源目錄中的圖片,加入圖片后會(huì)增大打包的包體體積琳拭,用的是相對(duì)路徑
  • Image.network:網(wǎng)絡(luò)資源圖片训堆,意思就是需要加入一段http://xxxx.xxx的這樣的網(wǎng)絡(luò)路徑地址
  • Image.file:加載本地圖片,就是加載本地文件中的圖片白嘁,這是一個(gè)絕對(duì)路徑坑鱼,跟包體無(wú)關(guān)
  • Image.memory:加載Uint8List資源圖片

fit屬性的設(shè)置

  • BoxFit.fill:全圖顯示,圖片會(huì)被拉伸絮缅,并充滿父容器
  • BoxFit.contain:全圖顯示鲁沥,顯示原比例呼股,可能會(huì)有空隙
  • BoxFix.cover:顯示可能拉伸,可能裁切画恰,充滿(圖片要充滿整個(gè)容器彭谁,還不變形 )
  • BoxFit.fitWidth:寬度充滿(橫向充滿),顯示可能拉伸允扇,可能裁切
  • BoxFit.fitHeight:高度充滿(豎向充滿),顯示可能拉伸缠局,可能裁切
  • BoxFit.scaleDown:效果和contain差不多,但是此屬性不允許顯示超過(guò)源圖片大小蔼两,可小不可大

圖片的混合模式

圖片混合模式(colorBlendMode)和color屬性配合使用甩鳄,能讓圖片改變顏色逞度,里面的模式非常多额划,產(chǎn)生的效果也非常豐富

child:new Image.network(
  'https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2247692397,1189743173&fm=5',
    color: Colors.greenAccent,
    colorBlendMode: BlendMode.darken,
),
  • color:是要混合的顏色,如果你只設(shè)置color是沒(méi)有意義的
  • colorBlendMode:是混合模式

repeat圖片重復(fù)

  • ImageRepeat.repeat :橫向和縱向都進(jìn)行重復(fù)档泽,直到鋪滿整個(gè)畫布
  • ImageRepeat.repeatX:橫向重復(fù)俊戳,縱向不重復(fù)
  • ImageRepeat.repeatY:縱向重復(fù),橫向不重復(fù)
child:new Image.network(
  'http://jspang.com/static/myimg/blogtouxiang.jpg',
   repeat: ImageRepeat.repeat,
),
body: Center(
          child: Container(
             child:new Image.network(
                  'https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2247692397,1189743173&fm=5',
                  scale: 1.0,
                  // fit: BoxFit.cover,
                  color: Colors.greenAccent,
                  colorBlendMode: BlendMode.darken,
                  repeat: ImageRepeat.repeat,
              ),
              width: 500.0,
              height: 600.0,
              color: Colors.lightBlue,
          ),
        ),

ListView列表組件簡(jiǎn)介

ListTile組件

body: new ListView(
  children:<Widget>[
    new ListTile(
      leading:new Icon(Icons.access_time),
      title:new Text('access_time')
    ),
    new ListTile(
      leading:new Icon(Icons.account_balance),
      title:new Text('account_balance')
    ),
  ]
),

圖片列表的使用

body: new ListView(
  children: <Widget>[
      new Image.network(     'https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2247692397,1189743173&fm=5'),
      new Image.network(        'https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=1569462993,172008204&fm=5'),
      new Image.network(     'https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=1853832225,307688784&fm=5')
          ],
        ),

橫向列表的使用

body: Center(
          child: Container(
            height: 200.0,
            child: new ListView(
              scrollDirection: Axis.horizontal,
              children: <Widget>[
                new Container(
                  width: 180.0,
                  color: Colors.lightBlue,
                ),new Container(
                  width: 180.0,
                  color: Colors.amber,
                ),new Container(
                  width: 180.0,
                  color: Colors.deepOrange,
                ),new Container(
                  width: 180.0,
                  color: Colors.deepPurpleAccent,
                )
              ],
            ),
          ),
        )

scrollDirection屬性

ListView組件的scrollDirection屬性只是兩個(gè)值馆匿,一個(gè)是橫向滾動(dòng)抑胎,一個(gè)是縱向滾動(dòng),默認(rèn)的就是垂直滾動(dòng)渐北,所以如果是垂直滾動(dòng)阿逃,一般不進(jìn)行設(shè)置

  • Axis.horizontal:橫向滾動(dòng)或者叫水平方向滾動(dòng)
  • Axis.vertical:縱向滾動(dòng)或者叫垂直方向滾動(dòng)

代碼優(yōu)化

// 使用類,減少嵌套
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context ){
      return MaterialApp(
        title:'ListView widget',
        home:Scaffold(
          body:Center(
          child:Container(
            height:200.0,
            child:MyList()
            ),
          ),
        ),
      );
  }
}
class MyList extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return ListView(
        scrollDirection: Axis.horizontal,
        children: <Widget>[
          new Container(
            width:180.0,
            color: Colors.lightBlue,
          ), new Container(
            width:180.0,
            color: Colors.amber,
          ), new Container(
            width:180.0,
            color: Colors.deepOrange,
          ),new Container(
            width:180.0,
            color: Colors.deepPurpleAccent,
          ),
        ],
    );
  }
}

List類型的使用

List是Dart的集合類型之一赃蛛,可以理解為數(shù)組恃锉,它聲明的幾種方式

  • var myList = List():非固定長(zhǎng)度的聲明
  • var myList = List(2):固定長(zhǎng)度的聲明
  • var myList = List<string>():固定類型的聲明方式
  • var myList = [1,2,3]:對(duì)List直接賦值

使用一個(gè)List傳遞,然后直接用List中的generate方法進(jìn)行生產(chǎn)List里的元素呕臂。最后生產(chǎn)一個(gè)帶值的List變量

void main () => runApp(MyApp(
  items: new List<String>.generate(1000, (i)=> "Item $i")
));
// main函數(shù)的runApp中調(diào)用了MyApp類破托,再使用類傳遞了一個(gè)item參數(shù),并使用generate生成器對(duì)item進(jìn)行賦值
// generate方法傳遞兩個(gè)參數(shù)歧蒋,第一個(gè)參數(shù)是生成的個(gè)數(shù)土砂,第二個(gè)是方法

接受參數(shù)

final List<String> items;
MyApp({Key key, @required this.items}):super(key:key)
// 構(gòu)造函數(shù),@required是比傳的意思谜洽,:super如果父類沒(méi)有無(wú)名無(wú)參的默認(rèn)構(gòu)造函數(shù)萝映,子類必須手動(dòng)調(diào)用一個(gè)父類構(gòu)造函數(shù)

動(dòng)態(tài)列表ListView.builder()

import 'package:flutter/material.dart';
void main () => runApp(MyApp(
   // 傳遞參數(shù)
  items: new List<String>.generate(1000, (i)=> "Item $i")
));
class MyApp extends StatelessWidget{
   // 接受參數(shù)
  final List<String> items;
  MyApp({Key key, @required this.items}):super(key:key);
  @override
  Widget build(BuildContext context ){
      return MaterialApp(
        title:'ListView widget',
        home:Scaffold(
          // 動(dòng)態(tài)列表
          body:new ListView.builder(
            itemCount:items.length,
            itemBuilder:(context,index){
              return new ListTile(
                title:new Text('${items[index]}'),
              );
            }
          )
        ),
      );
  }
}

GridView網(wǎng)格列表組件

網(wǎng)格列表常用來(lái)顯示多張圖片,類似于相冊(cè)功能

   body: new GridView.count(
          padding: const EdgeInsets.all(20.0),
          crossAxisSpacing: 10.0,
          crossAxisCount: 3,
          children: <Widget>[
            const Text('我的呱呱'),
            const Text('我喜歡吃'),
            const Text('我是個(gè)淑女的小姐姐'),
            const Text('我是個(gè)會(huì)寫代碼的萌妹紙'),
            const Text('我喜歡吃火鍋'),
            const Text('我喜歡看書(shū)')
          ],
        )
       // padding 內(nèi)邊距
       // crossAxisSpacing: 網(wǎng)格間的空擋阐虚,相當(dāng)于每個(gè)網(wǎng)格間的距離
       // crossAxisCount: 網(wǎng)格的列數(shù)序臂,相當(dāng)于一行放置網(wǎng)格的數(shù)量
  • GridView.count:創(chuàng)建一個(gè)在橫軸上具有固定數(shù)量網(wǎng)格塊的平鋪的布局

  • GridView.extent:使用具有最大橫軸范圍的網(wǎng)格塊創(chuàng)建布局

  • 自定義SliverGridDelegate:可以生成任意2D排列的子代,包括未對(duì)齊或重疊的排列

  • 要?jiǎng)?chuàng)建具有大量(或無(wú)限)個(gè)子節(jié)點(diǎn)的網(wǎng)絡(luò)敌呈,將GridView.builder構(gòu)造函數(shù)與gridDelegateSliverGridDelegateWithFixedCrossAxisCountSliverGridDelegateWithMaxCrossAxisExtent 一起使用

    http://www.reibang.com/p/aec6fee34f70(詳細(xì)信息)

import 'package:flutter/material.dart';
// 主函數(shù)(入口函數(shù))
void main() => runApp(MyApp(
  // 傳遞參數(shù)
  // items: new List<String>.generate(10, (i)=>"Item $i")
));

// 聲明MyApp類
class MyApp extends StatelessWidget{
  // 接受參數(shù)
  // final List<String> items;
  // MyApp({Key key, @required this.items}):super(key:key);
// 重寫build方法
  @override
  Widget build(BuildContext context){
    // 返回一個(gè)Material風(fēng)格的組件
    return MaterialApp(
      title: '好好學(xué)習(xí)',
      home: Scaffold(
        // 主體中間區(qū)域
        body: new GridView(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            mainAxisSpacing: 2.0,
            crossAxisSpacing: 2.0,
            childAspectRatio: 0.7
          ),
          children: <Widget>[
            new Image.network('http://img5.mtime.cn/mt/2018/10/22/104316.77318635_180X260X4.jpg',fit:BoxFit.cover),
            new Image.network('http://img5.mtime.cn/mt/2018/10/10/112514.30587089_180X260X4.jpg',fit:BoxFit.cover),
            new Image.network('http://img5.mtime.cn/mt/2018/11/13/093605.61422332_180X260X4.jpg',fit:BoxFit.cover),
            new Image.network('http://img5.mtime.cn/mt/2018/11/07/092515.55805319_180X260X4.jpg',fit:BoxFit.cover),
            new Image.network('http://img5.mtime.cn/mt/2018/11/21/090246.16772408_135X190X4.jpg',fit:BoxFit.cover),
            new Image.network('http://img5.mtime.cn/mt/2018/11/17/162028.94879602_135X190X4.jpg',fit:BoxFit.cover),
            new Image.network('http://img5.mtime.cn/mt/2018/11/19/165350.52237320_135X190X4.jpg',fit:BoxFit.cover),
            new Image.network('http://img5.mtime.cn/mt/2018/11/16/115256.24365160_180X260X4.jpg',fit:BoxFit.cover),
            new Image.network('http://img5.mtime.cn/mt/2018/11/20/141608.71613590_135X190X4.jpg',fit:BoxFit.cover),
          ],
        )
      ),
    );
  }
}
// childAspectRatio:寬高比

布局

第01節(jié)水平布局Row的使用

Flutter中的row控件是水平控件贸宏,可以讓Row子元素進(jìn)行水平排列

Row控件可以分為靈活排列非靈活排列兩種

不靈活水平布局:根據(jù)Row子元素的大小造寝,進(jìn)行布局,如果子元素不足吭练,會(huì)留有空間诫龙,如果子元素超出,會(huì)警告

//按鈕
 new RaisedButton(
    onPressed: (){
    },
    color:Colors.orangeAccent,
    child: new Text('黃色按鈕'),
 ), 

靈活布局:使用Expanded來(lái)解決空隙問(wèn)題鲫咽,在按鈕外邊加入Expanded就可以了

Expanded(
    child: new RaisedButton(
       onPressed: (){},
       color: Colors.pinkAccent,
       child: new Text('粉色按鈕'),
     )
   )

注意:還可以靈活和不靈活混合使用

第02節(jié):垂直布局Column組件

Column組件就是垂直布局控件签赃,能夠?qū)⒆咏M件垂直排列

body:Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
            Text('I am JSPang'),
            Text('my website is jspang.com'),
            Text('I love coding')
        ],
    )
// CrossAxisAlignment.star:居左對(duì)齊。
// CrossAxisAlignment.end:居右對(duì)齊分尸。
// CrossAxisAlignment.center:居中對(duì)齊锦聊。

主軸和副軸

mainAxisAlignment 主軸對(duì)齊方式

  • main軸:主軸(根據(jù)組件判斷主軸,column組件箩绍,和Row組件)
  • cross軸:副軸

第03節(jié):Stack層疊布局

// 聲明MyApp類
class MyApp extends StatelessWidget{
  // 接受參數(shù)
  // final List<String> items;
  // MyApp({Key key, @required this.items}):super(key:key);
// 重寫build方法
  @override
  Widget build(BuildContext context){
    // 返回一個(gè)Material風(fēng)格的組件
    var stack = new Stack(
      alignment: const FractionalOffset(0.5, 0.95),
      children: <Widget>[
        new CircleAvatar(
          backgroundImage: new NetworkImage('https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2247692397,1189743173&fm=5'),
          radius: 100.0,
        ),
        new Container(
          decoration: new BoxDecoration(
            color: Colors.lightGreen
          ),
          padding: EdgeInsets.fromLTRB(20.0,3.0,20.0,3.0),
          child: Text('布偶',style: TextStyle(fontSize: 18.0,color: Colors.blueGrey),),
        )
      ],
    );
    return MaterialApp(
      title: '好好學(xué)習(xí)',
      home: Scaffold(
        appBar: new AppBar(
          title: new Text('水平方向布局'),
        ),
        // 主體中間區(qū)域
        body: Center(
          child:stack
        )
      ),
    );
  }
}

重疊布局的alignment屬性

alignment屬性是控制層疊的位置的孔庭,建議在兩個(gè)內(nèi)容進(jìn)行層疊時(shí)使用,它有兩個(gè)值X軸距離和Y軸距離材蛛,值是從0到1的圆到,都是從上層容器的左上角開(kāi)始計(jì)算的

alignment: const FractionalOffset(0.5, 0.8),

CircleAvatar組件的使用

CircleAvatar這個(gè)常用來(lái)作頭像,組件里面有個(gè)radius的值可以設(shè)置圖片的弧度

new CircleAvatar(
          backgroundImage: new NetworkImage('https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2247692397,1189743173&fm=5'),
          radius: 100.0,
        ),

Stack的Position屬性

層疊定位組件

Positioned組件的屬性

  • bottom:距離層疊組件下邊的距離
  • left:距離層疊組件左邊的距離
  • right:距離層疊組件右邊的距離
  • top:距離層疊組件上邊的距離
  • width:距離層疊組件定位組件的寬度
  • height:距離層疊組件定位組件的高度
 new Positioned(
     bottom:10.0,
     right:10.0,
     child: new Text('技術(shù)胖'),
 )

第05節(jié):卡片組件布局

類似與ViewList卑吭,但是列表會(huì)以物理卡片的形態(tài)進(jìn)行展示

卡片式布局默認(rèn)撐滿整個(gè)外部容器芽淡,如果想要設(shè)置卡片的高度,需要在外部容器就進(jìn)行制定

var card = new Card(
     child: Column(
       children: <Widget>[
        ListTile(
           title: Text('湖南省益陽(yáng)市',style:TextStyle(fontWeight: FontWeight.w500)),
           subtitle: Text('伊:13710145724'),
           leading: new Icon(Icons.account_box,color:Colors.lightBlue),
          ),
        new Divider(),
        ListTile(
          title: Text('湖南省長(zhǎng)沙市',style:TextStyle(fontWeight: FontWeight.w500)),
          subtitle: Text('伊:13710145724'),
          leading: new Icon(Icons.account_box,color:Colors.lightBlue),
        ),
        new Divider(),
        ListTile(
          title: Text('湖南省常德市',style:TextStyle(fontWeight: FontWeight.w500)),
          subtitle: Text('伊:13710145724'),
          leading: new Icon(Icons.account_box,color:Colors.lightBlue),
        ),
        new Divider(),
       ],
     ),
   );
//new Divider()分割線

頁(yè)面導(dǎo)航和其他

第01節(jié):一般頁(yè)面導(dǎo)航和返回

RaiseButton按鈕組件

基本屬性:

  • child:可以放入容器豆赏,圖標(biāo)挣菲,文字
  • onPressed:點(diǎn)擊事件的響應(yīng),一般會(huì)調(diào)用Navigator組件

Navigator.push和Navigator.pop

  • Navigator.push:是跳轉(zhuǎn)到下一個(gè)頁(yè)面掷邦,他要接受兩個(gè)參數(shù)一個(gè)是上下文context白胀,另一個(gè)是要跳轉(zhuǎn)的函數(shù)
  • Navigator.pop:是返回到上一個(gè)頁(yè)面,使用時(shí)傳遞一個(gè)context參數(shù)耙饰,注意纹笼,必須是有上級(jí)頁(yè)面的,也就是說(shuō)上級(jí)頁(yè)面使用了Navigator.push
import 'package:flutter/material.dart';
void main(){
  runApp(MaterialApp(
    title:'導(dǎo)航演示1',
    home:new FirstScreen()
  ));
}
class FirstScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return new Scaffold(
      appBar: AppBar(title:Text('導(dǎo)航頁(yè)面')),
      body:Center(
        child:RaisedButton(
          child:Text('查看商品詳情頁(yè)面'),
          onPressed: (){
            Navigator.push(context,new  MaterialPageRoute(
              builder:(context) =>new SecondScreen())
            );
          },
        )
      )
    );
  }
}
class SecondScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return Scaffold(
      appBar:AppBar(title:Text('技術(shù)胖商品詳情頁(yè)')),
      body:Center(
        child:RaisedButton(
          child:Text('返回'),
          onPressed: (){
            Navigator.pop(context);
          },
      ))
    );
  }
}

第02節(jié):導(dǎo)航參數(shù)的傳遞和接受

Awesome Flutter snippets插件的使用:幫助快速生成常用的Flutter代碼片段


聲明數(shù)據(jù)結(jié)構(gòu)類

Dart中可以使用類來(lái)抽象一個(gè)數(shù)據(jù)苟跪,比如我們模仿一個(gè)商品信息廷痘,有商品標(biāo)題和商品描述。定義一個(gè)product類件已,里面有兩個(gè)字符變量笋额,title和description

  • title:商品標(biāo)題
  • description:商品詳情描述
class Product{
    final String title;
    final String description;
    Product(this.title,this.description)
}
// 主函數(shù),動(dòng)態(tài)函數(shù)
void main(){
  runApp(MaterialApp(
    title:'數(shù)據(jù)傳遞案例',
    home:ProductList(
      products:List.generate(
        20, 
        (i)=>Product('商品 $i','這是一個(gè)商品詳情篷扩,編號(hào)為:$i')
      ),
    )
  ));
}
// 動(dòng)態(tà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:(){
            }
          );
        },
      )
    );
  }
}

導(dǎo)航參數(shù)的傳遞

使用Navigator組件兄猩,然后使用路由MaterialPageRouter傳遞參數(shù)

Navigator.push(
    context,
    MaterialPageRouter(
    builder:(context)=>new       ProductDetail(product:products[index])
    )
)

第04節(jié):頁(yè)面跳轉(zhuǎn)并返回?cái)?shù)據(jù)

異步請(qǐng)求和等待

Dart的異步請(qǐng)求和等待和ES6的方法很像,直接使用async....await就可以實(shí)現(xiàn)

// async 是啟用異步方法
_navigateToXiaoJieJie(BuildContext context) async{
    final result = await Navigator.push(
        context,
        MaterialPageRouter(
            builder:(context)=>Xiaojiejie()
        )
    );
    Scaffold.of(context).showSnackBar(SnackBar(content:Text('$result')));
}

SnackBar的使用

SnackBar是用戶操作后,顯示提示信息的一個(gè)控件枢冤,類似Tost鸠姨,會(huì)自動(dòng)隱藏。SnackBar是以ScaffoldshowSnackBar方法來(lái)進(jìn)行顯示的

Scaffold.of(context).showSnackBar(SnackBar(content:Text('$result')))

返回?cái)?shù)據(jù)的方式

返回?cái)?shù)據(jù)其實(shí)是特別容易的淹真,只要在返回時(shí)帶第二個(gè)參數(shù)就可以了

Navigator.pop(context,'xxx');//xxx就是返回的參數(shù)

Demo

import 'package:flutter/material.dart';
void main(){
  runApp(MaterialApp(
    title: '頁(yè)面跳轉(zhuǎn)放回?cái)?shù)據(jù)',
    home: FirstPage(),  
  ));
}

class FirstPage extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('找伊大美女要電話號(hào)碼'),
      ),
      body: Center(
        child: RouterButton(),
      ),
    );
  }
}


class RouterButton extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return RaisedButton(
      child: Text('伊伊是大美女'),
      onPressed: (){
        _navigateToXiaoJieJie(context);
      },
    );
  }

  _navigateToXiaoJieJie(BuildContext context) async{ //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) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('我是小姐姐'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            RaisedButton(
              child: Text('大長(zhǎng)腿小姐姐'),
              onPressed: (){
                Navigator.pop(context,'大長(zhǎng)腿姐姐:13710145724');
              },
            ),
            RaisedButton(
              onPressed: (){
                Navigator.pop(context,'小蠻腰姐姐:13710145724');
              },
              child: Text('小蠻腰小姐姐'),
            )
          ],
        ),
      ),
    );
  }
}

第05節(jié):靜態(tài)資源和項(xiàng)目圖片的處理

注意:pubspec.yaml文件讶迁,配置項(xiàng)目資源文件,在里面聲明資源文件

  assets:
    - images/blogtouxiang.jpg

使用項(xiàng)目圖片資源

import 'package:flutter/material.dart';
void main()=>runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Image.asset('images/blogtouxiang.jpg'),
    );
  }
}

第06節(jié):Flutter客戶端打包

配置APP的圖標(biāo)

項(xiàng)目根目錄/android/app/src/main/res

AndroidManifest.xml文件

這個(gè)文件主要用來(lái)配置APP的名稱核蘸,圖標(biāo)和系統(tǒng)權(quán)限巍糯,所在的目錄在

項(xiàng)目根目錄/android/app/src/main/AndroidManifest.xml
android:label="flutter_app"   //配置APP的名稱,支持中文
android:icon="@mipmap/ic_launcher" //APP圖標(biāo)的文件名稱

生成keystore

打包詳情

https://jspang.com/post/flutter4.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末客扎,一起剝皮案震驚了整個(gè)濱河市祟峦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌徙鱼,老刑警劉巖宅楞,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異疆偿,居然都是意外死亡咱筛,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門杆故,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人溉愁,你說(shuō)我怎么就攤上這事处铛。” “怎么了拐揭?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵撤蟆,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我堂污,道長(zhǎng)家肯,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任盟猖,我火速辦了婚禮讨衣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘式镐。我一直安慰自己反镇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布娘汞。 她就那樣靜靜地躺著歹茶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惊豺,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天燎孟,我揣著相機(jī)與錄音,去河邊找鬼尸昧。 笑死缤弦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的彻磁。 我是一名探鬼主播碍沐,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼衷蜓!你這毒婦竟也來(lái)了累提?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤磁浇,失蹤者是張志新(化名)和其女友劉穎斋陪,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體置吓,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡无虚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衍锚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片友题。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖戴质,靈堂內(nèi)的尸體忽然破棺而出度宦,到底是詐尸還是另有隱情,我是刑警寧澤告匠,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布戈抄,位于F島的核電站,受9級(jí)特大地震影響后专,放射性物質(zhì)發(fā)生泄漏划鸽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一戚哎、第九天 我趴在偏房一處隱蔽的房頂上張望裸诽。 院中可真熱鬧,春花似錦建瘫、人聲如沸崭捍。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)殷蛇。三九已至实夹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間粒梦,已是汗流浹背亮航。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留匀们,地道東北人缴淋。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像泄朴,于是被迫代替她去往敵國(guó)和親重抖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 特別說(shuō)明 當(dāng)前博客平臺(tái)賬號(hào)已廢棄祖灰,如果有使用細(xì)節(jié)問(wèn)題請(qǐng)前往我新博客平臺(tái)進(jìn)行討論交流钟沛。 個(gè)人博客平臺(tái) HuRuWo的...
    善篤有余劫閱讀 4,957評(píng)論 0 30
  • 國(guó)慶后面兩天在家學(xué)習(xí)整理了一波flutter,基本把能擼過(guò)能看到的代碼都過(guò)了一遍局扶,此文篇幅較長(zhǎng)恨统,建議保存(star...
    Nealyang閱讀 4,345評(píng)論 1 17
  • 已經(jīng)很長(zhǎng)的時(shí)間, 似乎是忘了年月三妈。 她聲音里透露出些許不安畜埋, 我知道一定是風(fēng)霜侵襲了她, 那曾烏黑亮麗的頭發(fā)畴蒲。 隱...
    只是從未孤獨(dú)閱讀 124評(píng)論 2 0
  • 一大早我們坐106又坐39路悠鞍,雖然下著雨,但也不能阻擋我們要去看年糕的心情饿凛,我們等公交車等了很久狞玛,終于有一輛39路...
    輕舞飛揚(yáng)nice閱讀 154評(píng)論 0 1
  • 今天給大家推薦的這部勵(lì)志電影,《麥克法蘭》是由妮基·卡羅執(zhí)導(dǎo)锭亏,凱文·科斯特納纠吴、摩根·塞勒、瑪麗亞·貝羅等主演的運(yùn)動(dòng)...
    monasp閱讀 345評(píng)論 0 0