為您解碼網(wǎng)站建設的點點滴滴
發(fā)表日期:2019-01 文章編輯:小燈 瀏覽次數(shù):2646
在flutter中,一切的顯示都是在Widget中,Widget 是一切顯示的基礎(chǔ)。
作為響應式的渲染,屬于 MVVM 的實現(xiàn)機制。我們可以通過修改數(shù)據(jù),再用setState 設置數(shù)據(jù),F(xiàn)lutter 會自動通過綁定的數(shù)據(jù)更新 Widget 。所以我們需要做的就是實現(xiàn) Widget 界面,并且將其與對應的數(shù)據(jù)綁定起來。
那么這里是不是又只能用setState進行響應式的開發(fā)呢?并不是的。
Widget作為抽象類,下面是分為有狀態(tài)(StatefulWidget)和無狀態(tài)(StatelessWidget)兩種的。而這里的有狀態(tài)Widget就是進行響應式開發(fā)來使用的,而無狀態(tài)的StatelessWidget同樣可以使用,來進行構(gòu)造不需要變化的控件。
這里是我根據(jù)繼承關(guān)系繪制的UML圖,暫且把需要的先畫了,有些簡單畫的是我覺得沒必要說的 hhh
這里最重要的一個父類就是Widget了,里面有個
final Key key;
是所有子類都需要繼承并使用的。這里是表示的一個密鑰,其實就是控件的標識。注釋里說明:
//控制一個Widgets如何替換樹中的另一個Widgets。 //如果兩個Widgets的[runtimeType]和[key]屬性分別是[operator ==],則新Widgets將替換舊//Widgets //更新底層元素(即通過使用新Widgets調(diào)用[Element.update])。 //否則,將從樹中刪除舊元素,將新窗口Widgets擴展為元素,并將新元素插入樹中 //此外,使用[GlobalKey]作為窗口Widgets的[key]允許元素在樹周圍移動(更改父級)而///不會丟失狀態(tài)。//當找到一個新的Widgets時(它的鍵和類型與同一位置的前一個Widgets不匹配), //但是在前一幀的樹中的某個地方有一個具有相同全局鍵的Widgets,那么該Widgets的元素將被移動到 新的位置。 //通常,作為另一個Widgets的唯一子節(jié)點的Widgets不需要一個明確的密鑰。
StatefulWidget和StatelessWidget前面有過敘述,接下來還會進行敘述。我們看看其他三個。
ProxyWidget:提供子窗口Widgets的窗口Widgets,而不是構(gòu)建新窗口Widgets。 (其下有很多子類)
RenderObjectWidget:提供RenderObjectElement的配置,包裝RenderObject,并提供應用程序的實際呈現(xiàn)。(實際就是渲染W(wǎng)idget)
PreferredSizeWidget:Widgets的接口,如果它不受限制,可以返回此Widgets所希望的大小。
Widget 和 Widget 之間通過 child: 進行嵌套。其中有的 Widget 只能有一個 child,而有的Widget可以有多個child。
我們可以寫一個demo來測試一下StatelessWidget。
void main() => runApp(MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: new TestDemo(title: 'test demo',) ); } } class TestDemo extends StatelessWidget{ TestDemo({Key key, this.title}) : super(key: key); final String title;@override Widget build(BuildContext context) { // TODO: implement build return new Scaffold( appBar: new AppBar( title: new Text('flutter Bar'), ), body: new Center( child: new Text(title), ), ); } }
可以看到,StatelessWidget類內(nèi)部一定有一個build方法返回一個Widget。而且home屬性傳入的是一個Widget。這里的home是調(diào)用TestDemo返回了Scaffold。然后MyApp再返回MaterialApp。
MaterialApp是材料App,一般作為APP頂層的主頁入口,可配置主題,多語言,路由等。
Scaffold是腳手架,一般用戶頁面的承載Widget,包含appbar、snackbar、drawer等material design的設定。
AppBar是安卓的ToolBar一樣的控件。
里面還可以返回一些其余控件,比如說AppBar有標題,二級頁面返回按鍵。Scaffold有懸浮按鈕等。
class TestDemo extends StatelessWidget{ TestDemo({Key key, this.title}) : super(key: key); final String title;@override Widget build(BuildContext context) { // TODO: implement build return new Scaffold( appBar: new AppBar( title: new Text('flutter Bar'), leading: new Icon(Icons.list), ), body: new Center( child: new Text(title), ), floatingActionButton: FloatingActionButton( tooltip: 'Increment', child: new Icon(Icons.add), ), ); } }
2.PNG 如圖所示。
需要創(chuàng)建管理的是主要是 State , 通過 State 的 build 方法去構(gòu)建控件。在 State 中,你可以動態(tài)改變數(shù)據(jù),也就是繼承 State<>的實現(xiàn)。在 setState 之后,改變的數(shù)據(jù)會觸發(fā) Widget 重新構(gòu)建刷新。
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), ), // This trailing comma makes auto-formatting nicer for build methods. ); } }
這里是默認創(chuàng)建的flutter項目中的代碼,大致邏輯就是點擊floatingActionButton響應,調(diào)用_incrementCounter函數(shù)。函數(shù)內(nèi)是setState。setState 之后,改變的數(shù)據(jù)會觸發(fā) Widget 重新構(gòu)建刷新,更新counter的Text( '$_counter', )
大致邏輯就是如此,需要編寫的地方就是繼承了state<>的類了,而state的生命周期:
注意一下 child: Column(),這里面是下面要講的內(nèi)容:布局。
布局文檔
常用的大概有:
Row:一個以水平數(shù)組的形式顯示其子部件的Widget
children是一個Widget數(shù)組(可以有多個子 Widget),當然這里如果一直顯示的話會存在越界的情況。
Colum:一個以豎直數(shù)組的形式顯示其子部件的Widget。
children是一個Widget數(shù)組(可以有多個子 Widget)
Container:一個結(jié)合了常見的繪制,定位和大小調(diào)整Widget
children是一個Widget(只有一個子 Widget),默認充滿,包含color、寬高、decoration 等等配置。
Expanded:創(chuàng)建一個Widget,用于展開Row,Column或Flex的子項展開以填充主軸中的可用空間。
children是一個Widget(只有一個子 Widget)。在 Colum 和 Row 中充滿。
Stack:一個相對于它的框的邊緣來定位它的子部件的Widget。
children是一個Widget數(shù)組(有多個子 Widget)。 子Widget堆疊在一起。
Card :大致效果為Android的CardView
children是一個Widget(只有一個子 Widget)
其余還有一些輔助的布局如:Center(),padding()等等。
我們使用一些來試試:
void main() => runApp(MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', home:new TestDemo() ); } }class TestDemo extends StatelessWidget{ @override Widget build(BuildContext context) { // TODO: implement build return new Scaffold( appBar: AppBar( brightness: Brightness.light, title: Text('TestCard'), ),body: Column( children: <Widget>[ Card( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ AspectRatio( aspectRatio: 18.0 / 11.0, child: Icon(Icons.favorite), ), Padding( padding: EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text('Title'), SizedBox(height: 8.0), Text('Secondary Text'), ], ), ), ], ), ), Expanded( child:Text('這是一個特別特別特別特別特別長的Text,以便于測試我們需要的效果,'), ), ], ) ); } }
測試效果如圖:
日期:2018-10 瀏覽次數(shù):7253
日期:2018-12 瀏覽次數(shù):4328
日期:2018-07 瀏覽次數(shù):4876
日期:2018-12 瀏覽次數(shù):4174
日期:2018-09 瀏覽次數(shù):5502
日期:2018-12 瀏覽次數(shù):9922
日期:2018-11 瀏覽次數(shù):4804
日期:2018-07 瀏覽次數(shù):4578
日期:2018-05 瀏覽次數(shù):4859
日期:2018-12 瀏覽次數(shù):4324
日期:2018-10 瀏覽次數(shù):5139
日期:2018-12 瀏覽次數(shù):6212
日期:2018-11 瀏覽次數(shù):4464
日期:2018-08 瀏覽次數(shù):4592
日期:2018-11 瀏覽次數(shù):12629
日期:2018-09 瀏覽次數(shù):5579
日期:2018-12 瀏覽次數(shù):4832
日期:2018-10 瀏覽次數(shù):4187
日期:2018-11 瀏覽次數(shù):4528
日期:2018-12 瀏覽次數(shù):6063
日期:2018-06 瀏覽次數(shù):4007
日期:2018-08 瀏覽次數(shù):5436
日期:2018-10 瀏覽次數(shù):4457
日期:2018-12 瀏覽次數(shù):4525
日期:2018-07 瀏覽次數(shù):4362
日期:2018-12 瀏覽次數(shù):4500
日期:2018-06 瀏覽次數(shù):4383
日期:2018-11 瀏覽次數(shù):4375
日期:2018-12 瀏覽次數(shù):4249
日期:2018-12 瀏覽次數(shù):5283
Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.