寫了幾天的基礎控件,大家對於flutter有了一個初步的認識,但是還是會記不住,不過我相信寫出來的代碼應該很舒服了,起碼我是這麼感覺的,代碼廢的地方几乎沒有,一氣呵成~接下來繼續瞭解佈局這塊,這塊學完,感覺就可以開始敲APP了,佈局是APP中的大項,其他的業務網絡什麼的都可以有現成不變的框架去套,只有佈局是跟著業務走的,所以這篇你只要一遍又一遍的去敲,熟練後你發現你代碼速度就上來了~嗯~
1.線性佈局Row和Column:Bootstrap記得吧 大學都玩過吧,跟這個很像的,根據水平和垂直方向來佈局,其實早就應該這麼玩了,當然適配就交給google了~哈哈~
import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); //Stateless widgets 是不可變的, 這意味著它們的屬性不能改變 - 所有的值都是最終的. //Stateful widgets 持有的狀態可能在widget生命週期中發生變化. 實現一個 stateful widget 至少需要兩個類: class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return new MaterialApp( title: "線性佈局Row和Column", home: new Scaffold( appBar: new AppBar( title: new Text("線性佈局Row和Column"), ), body: new Center( child: new FormTestRoute(), ), ), ); } } class FormTestRoute extends StatefulWidget { @override _FormTestRouteState createState() => new _FormTestRouteState(); } class _FormTestRouteState extends State { @override Widget build(BuildContext context) { return Scaffold( // title: "Form Test", body: Container( color: Colors.grey, child: Padding( padding: const EdgeInsets.all(10.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ Container( color: Colors.blue, child: Column( mainAxisSize: MainAxisSize.max, children: [ new Text("hi yun~"), new Text("I am lx"), ], ), ), Expanded( child: Container( color: Colors.green, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ new Text("hi yun~"), new Text("I am lx"), ], ), ), ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(" hello world "), Text(" I am Jack "), ], ), Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Text(" hello world "), Text(" I am Jack "), ], ), Row( mainAxisAlignment: MainAxisAlignment.end, textDirection: TextDirection.rtl, children: [ Text(" hello world "), Text(" I am Jack "), ], ), Row( crossAxisAlignment: CrossAxisAlignment.start, verticalDirection: VerticalDirection.up, children: [ Text(" hello world ", style: TextStyle(fontSize: 30.0),), Text(" I am Jack "), ], ), ], ), ), ), ); } }
2.彈性佈局Flex:這是大家熟悉的權重布方式
import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); //Stateless widgets 是不可變的, 這意味著它們的屬性不能改變 - 所有的值都是最終的. //Stateful widgets 持有的狀態可能在widget生命週期中發生變化. 實現一個 stateful widget 至少需要兩個類: class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return new MaterialApp( title: "彈性佈局Flex", home: new Scaffold( appBar: new AppBar( title: new Text("彈性佈局Flex"), ), body: new Center( child: new FormTestRoute(), ), ), ); } } class FormTestRoute extends StatefulWidget { @override _FormTestRouteState createState() => new _FormTestRouteState(); } class _FormTestRouteState extends State { @override Widget build(BuildContext context) { return Column( children: [ Flex( direction: Axis.horizontal, children: [ Expanded( flex: 1, child: Container( height: 30.0, color: Colors.red, ), ), Expanded( flex: 2, child: Container( height: 30.0, color: Colors.blue, ), ), ], ), Padding( padding: const EdgeInsets.only(top: 40.0), child: SizedBox( height: 100.0, child: Flex( direction: Axis.vertical, children: [ Expanded( flex: 2, child: Container( height: 30.0, color: Colors.red, ), ), Spacer( flex: 1, ), Expanded( flex: 1, child: Container( height: 30.0, color: Colors.blue, ), ), ], ), ), ), ], ); } }
3.流式佈局:之前的標籤flowlayout有印象吧 嗯~
import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); //Stateless widgets 是不可變的, 這意味著它們的屬性不能改變 - 所有的值都是最終的. //Stateful widgets 持有的狀態可能在widget生命週期中發生變化. 實現一個 stateful widget 至少需要兩個類: class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return new MaterialApp( title: "流式佈局", home: new Scaffold( appBar: new AppBar( title: new Text("流式佈局"), ), body: new Center( child: new FormTestRoute(), ), ), ); } } class FormTestRoute extends StatefulWidget { @override _FormTestRouteState createState() => new _FormTestRouteState(); } class _FormTestRouteState extends State { @override Widget build(BuildContext context) { return Column( children: [ Wrap( spacing: 2.0, runSpacing: 4.0, alignment: WrapAlignment.start, children: [ new Chip( label: new Text("hi yun1"), avatar: new CircleAvatar( backgroundColor: Colors.blue, child: Text("A"), ), ), new Chip( label: new Text("yun1"), avatar: new CircleAvatar( backgroundColor: Colors.blue, child: Text("Y1"), ), ), new Chip( label: new Text("hi yun2"), avatar: new CircleAvatar( backgroundColor: Colors.blueAccent, child: Text("Y2"), ), ), new Chip( label: new Text("yun3"), avatar: new CircleAvatar( backgroundColor: Colors.lightBlue, child: Text("Y3"), ), ), new Chip( label: new Text("hi yun4"), avatar: new CircleAvatar( backgroundColor: Colors.lightBlueAccent, child: Text("Y4"), ), ), new Chip( label: new Text("hi yun4"), avatar: new CircleAvatar( backgroundColor: Colors.lightBlueAccent, child: Text("Y4"), ), ), new Chip( label: new Text("hi yun4"), avatar: new CircleAvatar( backgroundColor: Colors.lightBlueAccent, child: Text("Y4"), ), ), new Chip( label: new Text("hi yun4"), avatar: new CircleAvatar( backgroundColor: Colors.lightBlueAccent, child: Text("Y4"), ), ), ], ), ], ); } }
4.層疊佈局:這個就厲害了,以後會用的多,相當於Framelayout
import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); //Stateless widgets 是不可變的, 這意味著它們的屬性不能改變 - 所有的值都是最終的. //Stateful widgets 持有的狀態可能在widget生命週期中發生變化. 實現一個 stateful widget 至少需要兩個類: class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return new MaterialApp( title: "層疊佈局", home: new Scaffold( appBar: new AppBar( title: new Text("層疊佈局"), ), body: new Center( // child: new FormTestRoute1(), child: new FormTestRoute2(), ), ), ); } } class FormTestRoute1 extends StatefulWidget { @override _FormTestRouteState1 createState() => new _FormTestRouteState1(); } class FormTestRoute2 extends StatefulWidget { @override _FormTestRouteState2 createState() => new _FormTestRouteState2(); } class _FormTestRouteState1 extends State { @override Widget build(BuildContext context) { return ConstrainedBox( constraints: BoxConstraints.expand(), child: Stack( alignment: Alignment.center, children: [ Container( child: Text( "hi yun1", style: TextStyle(color: Colors.white), ), color: Colors.red, ), Positioned( left: 18.0, child: Text("hi yun2"), ), Positioned( top: 18.0, child: Text("hi yun3"), ), ], ), ); } } class _FormTestRouteState2 extends State { @override Widget build(BuildContext context) { return ConstrainedBox( constraints: BoxConstraints.expand(), child: Stack( alignment: Alignment.center, fit: StackFit.expand, // 未定位widget佔滿Stack整個空間 children: [ Positioned( left: 18.0, child: Text("hi yun2"), ), Container( child: Text( "hi yun1", style: TextStyle(color: Colors.white), ), color: Colors.red, ), Positioned( top: 18.0, child: Text("hi yun3"), ), ], ), ); } }
總結:看上去其實不難,但是我發現在佈局的過程遇到的都是綜合的情況,所以還是要找一個比較複雜的佈局去試試,敲一敲,這樣你才會用的熟練~下期見~
關鍵字: Container Widget Scaffold