一区二区三区欧美日韩-一区二区三区欧美-一区二区三区免费在线视频-一区二区三区免费在线观看-久久精品店-久久精品第一页

歡迎您光臨深圳塔燈網(wǎng)絡科技有限公司!
電話圖標 余先生:13699882642

網(wǎng)站百科

為您解碼網(wǎng)站建設的點點滴滴

第一個Flutter項目--計數(shù)器示例

發(fā)表日期:2018-12 文章編輯:小燈 瀏覽次數(shù):2786

創(chuàng)建的flutter項目中,看一下這些部分是怎么組織起來的

在這個示例中,主要Dart代碼是在 lib/main.dart 文件中,下面我們看看該示例的源碼:

import 'package:flutter/material.dart';// 應用入口 void main() => runApp(MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( // 藍色主題primarySwatch: Colors.blue, ), // 應用首頁路由 home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key);final String title;@override _MyHomePageState createState() => _MyHomePageState(); }class _MyHomePageState extends State<MyHomePage> { int _counter = 0;void _incrementCounter() { setState(() { _counter++; }); }@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center(child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.display1, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), ); } } 

分析

1、導入包

import 'package:flutter/material.dart'; 

此行代碼作用是導入了Material UI組件庫。Material是一種標準的移動端和web端的視覺設計語言, Flutter默認提供了一套豐富的Material風格的UI組件。

2、應用入口

void main() => runApp(new MyApp()); 
  • 與C/C++、Java類似,F(xiàn)lutter 應用中main函數(shù)為應用程序的入口,main函數(shù)中調用了,runApp 方法,它的功能是啟動Flutter應用,它接受一個Widget參數(shù),在本示例中它是MyApp類的一個實例,該參數(shù)代表Flutter應用。
  • main函數(shù)使用了(=>)符號,這是Dart中單行函數(shù)或方法的簡寫。

3、應用結構

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( //應用名稱 title: 'Flutter Demo',theme: new ThemeData( //藍色主題 primarySwatch: Colors.blue, ), //應用首頁路由 home: new MyHomePage(title: 'Flutter Demo Home Page'), ); } } 
  • MyApp類代表Flutter應用,它繼承了 StatelessWidget類,這也就意味著應用本身也是一個widget。
  • 在Flutter中,大多數(shù)東西都是widget,包括對齊(alignment)、填充(padding)和布局(layout)。
  • Flutter在構建頁面時,會調用組件的build方法,widget的主要工作是提供一個build()方法來描述如何構建UI界面(通常是通過組合、拼裝其它基礎widget)。
  • MaterialApp 是Material庫中提供的Flutter APP框架,通過它可以設置應用的名稱、主題、語言、首頁及路由列表等。MaterialApp也是一個widget。
  • Scaffold 是Material庫中提供的頁面腳手架,它包含導航欄和Body以及FloatingActionButton(如果需要的話)。
  • home 為Flutter應用的首頁,它也是一個widget。

4、首頁

class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => new _MyHomePageState(); }class _MyHomePageState extends State<MyHomePage> {... } 

MyHomePage 是應用的首頁,它繼承自StatefulWidget類,表示它是一個有狀態(tài)的widget(Stateful widget)。現(xiàn)在,我們可以簡單認為Stateful widget 和Stateless widget有兩點不同:

  • Stateful widget可以擁有狀態(tài),這些狀態(tài)在widget生命周期中是可以變的,而Stateless widget是不可變的。
  • Stateful widget至少由兩個類組成:
    • 一個StatefulWidget類。
    • 一個 State類; StatefulWidget類本身是不變的,但是 State類中持有的狀態(tài)在widget生命周期中可能會發(fā)生變化。

_MyHomePageState類是MyHomePage類對應的狀態(tài)類。看到這里,細心的讀者可能已經(jīng)發(fā)現(xiàn),和MyApp 類不同, MyHomePage類中并沒有build方法,取而代之的是,build方法被挪到了_MyHomePageState方法中,至于為什么這么做,先留個疑問,在分析完完整代碼后再來解答。

接下來,我們看看_MyHomePageState中都包含哪些東西:

(1)狀態(tài)。

int _counter = 0; 

_counter 為保存屏幕右下角帶“?”號按鈕點擊次數(shù)的狀態(tài)。

(2)設置狀態(tài)的自增函數(shù)。

void _incrementCounter() { setState(() {_counter++; }); } 

當按鈕點擊時,會調用此函數(shù),該函數(shù)的作用是先自增_counter,然后調用setState 方法。setState方法的作用是通知Flutter框架,有狀態(tài)發(fā)生了改變,F(xiàn)lutter框架收到通知后,會執(zhí)行build方法來根據(jù)新的狀態(tài)重新構建界面, Flutter 對此方法做了優(yōu)化,使重新執(zhí)行變的很快,所以你可以重新構建任何需要更新的東西,而無需分別去修改各個widget。

(3)構建UI界面

構建UI界面的邏輯在build方法中,當MyHomePage第一次創(chuàng)建時,_MyHomePageState類會被創(chuàng)建,當初始化完成后,F(xiàn)lutter框架會調用Widget的build方法來構建widget樹,最終將widget樹渲染到設備屏幕上。所以,我們看看_MyHomePageState的build方法中都干了什么事:

Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text(widget.title), ), body: new Center( child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Text( 'You have pushed the button this many times:', ), new Text( '$_counter', style: Theme.of(context).textTheme.display1, ), ], ), ), floatingActionButton: new FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: new Icon(Icons.add), ), ); } 
  • Scaffold 是 Material庫中提供的一個widget, 它提供了默認的導航欄、標題和包含主屏幕widget樹的body屬性。widget樹可以很復雜。
  • body的widget樹中包含了一個Center widget,Center 可以將其子widget樹對其到屏幕中心, Center 子widget是一個Column widget,Column的作用是將其所有子widget沿屏幕垂直方向依次排列, 此例中Column包含兩個 Text子widget,第一個Text widget顯示固定文本 “You have pushed the button this many times:”,第二個Text widget顯示_counter狀態(tài)的數(shù)值。
  • floatingActionButton是頁面右下角的帶“?”的懸浮按鈕,它的onPressed屬性接受一個回調函數(shù),代表它本點擊后的處理器,本例中直接將_incrementCounter作為其處理函數(shù)。

現(xiàn)在,我們將整個流程串起來:當右下角的floatingActionButton按鈕被點擊之后,會調用_incrementCounter,在_incrementCounter中,首先會自增_counter計數(shù)器(狀態(tài)),然后setState會通知Flutter框架狀態(tài)發(fā)生變化,接著,F(xiàn)lutter會調用build方法以新的狀態(tài)重新構建UI,最終顯示在設備屏幕上。

為什么要將build方法放在State中,而不是放在StatefulWidget中?

這主要是為了開發(fā)的靈活性。如果將build()方法在StatefulWidget中則會有兩個問題:

  • 狀態(tài)訪問不便

試想一下,如果我們的Stateful widget 有很多狀態(tài),而每次狀態(tài)改變都要調用build方法,由于狀態(tài)是保存在State中的,如果將build方法放在StatefulWidget中,那么構建時讀取狀態(tài)將會很不方便,如果真的將build方法放在StatefulWidget中的話,由于構建用戶界面過程需要依賴State,所以build方法將必須加一個State參數(shù),大概是下面這樣:

Widget build(BuildContext context, State state){ //state.counter ... } 

這樣的話就只能將State的所有狀態(tài)聲明為公開的狀態(tài),這樣才能在State類外部訪問狀態(tài),但將狀態(tài)設置為公開后,狀態(tài)將不再具有私密性,這樣依賴,對狀態(tài)的修改將會變的不可控。將build()方法放在State中的話,構建過程則可以直接訪問狀態(tài),這樣會很方便。

  • 繼承StatefulWidget不便

例如,F(xiàn)lutter中有一個動畫widget的基類AnimatedWidget,它繼承自StatefulWidget類。AnimatedWidget中引入了一個抽象方法build(BuildContext context),繼承自AnimatedWidget的動畫widget都要實現(xiàn)這個build方法。現(xiàn)在設想一下,如果StatefulWidget 類中已經(jīng)有了一個build方法,正如上面所述,此時build方法需要接收一個state對象,這就意味著AnimatedWidget必須將自己的State對象(記為_animatedWidgetState)提供給其子類,因為子類需要在其build方法中調用父類的build方法,代碼可能如下:

class MyAnimationWidget extends AnimatedWidget{ @override Widget build(BuildContext context, State state){ //由于子類要用到AnimatedWidget的狀態(tài)對象_animatedWidgetState, //所以AnimatedWidget必須通過某種方式將其狀態(tài)對象_animatedWidgetState //暴露給其子類super.build(context, _animatedWidgetState) } } 

這樣很顯然是不合理的,因為

  • AnimatedWidget的狀態(tài)對象是AnimatedWidget內部實現(xiàn)細節(jié),不應該暴露給外部。
  • 如果要將父類狀態(tài)暴露給子類,那么必須得有一種傳遞機制,而做這一套傳遞機制是無意義的,因為父子類之間狀態(tài)的傳遞和子類本身邏輯是無關的。

綜上所述,可以發(fā)現(xiàn),對于StatefulWidget,將build方法放在State中,可以給開發(fā)帶來很大的靈活性。


本頁內容由塔燈網(wǎng)絡科技有限公司通過網(wǎng)絡收集編輯所得,所有資料僅供用戶學習參考,本站不擁有所有權,如您認為本網(wǎng)頁中由涉嫌抄襲的內容,請及時與我們聯(lián)系,并提供相關證據(jù),工作人員會在5工作日內聯(lián)系您,一經(jīng)查實,本站立刻刪除侵權內容。本文鏈接:http://www.junxiaosheng.cn/18076.html
相關APP開發(fā)
 八年  行業(yè)經(jīng)驗

多一份參考,總有益處

聯(lián)系深圳網(wǎng)站公司塔燈網(wǎng)絡,免費獲得網(wǎng)站建設方案及報價

咨詢相關問題或預約面談,可以通過以下方式與我們聯(lián)系

業(yè)務熱線:余經(jīng)理:13699882642

Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.    

主站蜘蛛池模板: 摸老师丝袜小内内摸出水| 天天插天天射天天干| 亚洲午夜精品一区二区公牛电影院| 成人免费观看在线视频| 免费麻豆国产黄网站在线观看| 一手揉着乳头一手模仿抽插视频| 国产精华av午夜在线观看| 日本高清免费一本在线观看| 中文字幕一区二区三区在线不卡| 精品久久久久中文字幕加勒比东京热| 午夜宅宅伦电影网| 国产成人无码区免费内射一片色欲| 日本三级黄色大片| yellow片高清视频免费看| 欧美成人一区二免费视频| 97国产在线观看| 蜜臀AV999无码精品国产| 中文字幕本庄优花喂奶| 久久精品一区二区三区资源网| 亚洲免费片| 红尘影院在线观看| 亚洲人成网站在线播放| 僵尸女av| 亚洲永久精品ww47| 久久精品亚洲国产AV涩情| 在线va无卡无码高清| 久久热最新网站获取3| 中文字幕按摩| 欧美18精品久久久无码午夜福利| 99爱视频在线观看| 琪琪电影午夜理论片YY6080| vagaa哇嘎黄短片| 日本一二三区视频在线| 国产超碰精久久久久久无码AV| 少妇高潮惨叫久久久久久电影| 国产成人a v在线影院| 小黄文纯肉污到你湿| 国语自产偷成人精品视频| 一本之道高清在线观看免费| 久久这里只精品国产99re66| 91桃色污无限免费看|