Flutter第3天--基礎控制元件(上)

張風捷特烈發表於2018-12-18

Flutter七日遊第三天:2018-12-18 天氣:晴朗

零、前言

浪了兩天,Dart語法基本上熟悉了,繪圖也不怕了,現在進入正軌,繼續浪~
今天來學些枯燥的東西了--基礎控制元件,戒驕戒躁,基礎還是要好好掌握。
本文目的在於儘可能看清控制元件的全域性(細枝末節點到為止),詳細用法等佈局實戰再細說吧
本文能用圖的,儘量不用字(看完你可能會覺得我腦洞有點大),廢話不多說,進入今天的內容


一、Widget簡入

Widget:[小器具,裝飾品,視窗小部件],以後簡稱:控制元件
下面看一下Widget樹:(只延伸到下代)

Widget樹.png


1.StatelessWidgetStatefulWidget

目前出現在我眼前的只這有兩個,所以先只看這兩個:

StatelessWidget:原始碼第一句話:
---->A widget that does not require mutable state.
---->一個不需要變動狀態的控制元件

StatefulWidget :原始碼第一句話:
---->A widget that has mutable state.
---->一個可變動狀態的控制元件
複製程式碼

2.StatelessWidget一共就有三個方法:

StatelessWidget.png

-------->[構造方法,需要一個key,而且老爸已經給他了]----
/// Initializes [key] for subclasses.
const StatelessWidget({ Key key }) : super(key: key);

-------->[createElement方法複寫Widget方法,使用StatelessElement--tag1--自給自足]
/// It is uncommon for subclasses to override this method.
//子類重寫此方法是不常見的。----所以就不要沒事找事了
StatelessElement createElement() => StatelessElement(this);

--tag1-->[StatelessElement,接收一個StatelessWidget]
/// An [Element] that uses a [StatelessWidget] as its configuration.
class StatelessElement extends ComponentElement {
 /// Creates an element that uses the given widget as its configuration.
  StatelessElement(StatelessWidget widget) : super(widget);
  
-------->[使用現在要關注的只有:build方法--]
/// Describes the part of the user interface represented by this widget.  
//描述此控制元件呈現在使用者介面上的部分
  @protected
  Widget build(BuildContext context);//空實現
複製程式碼

3.初始專案看StatelessWidget:

StatelessWidget映入眼簾,可見該類內部一定有一個build方法返回一個Widget

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.lightBlue,
      ),
      home:MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

//不難看出MaterialApp是一個Widget,而且至少有title,theme,home三個屬性
而且home傳入的是一個Widget
複製程式碼

4.恭喜達成成就:Widget原始碼偷窺者, 成就獎勵:三張卡片:

卡片初始屬性:見白框(PS:屬性會隨著你的閱歷變多哦)

- - -
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)

二、Flutter卡牌遊戲Start

接下來會列出一長串屬性,並挑選些簡單的屬性測試一下
如果你覺得及其無聊,列屬性的地方可以跳過,基本上每三個做一個小測試

1:MaterialApp--材料App

An application that uses material design.原始碼如是說:一個使用材料設計的App
繼承自StatefulWidget,欄位蠻多的,先列一下,看看現在用到的,其他的用到再說吧。

class MaterialApp extends StatefulWidget 

    this.navigatorKey,
    this.home,//--->tag1<---
    this.routes = const <String, WidgetBuilder>{},
    this.initialRoute,
    this.onGenerateRoute,
    this.onUnknownRoute,
    this.navigatorObservers = const <NavigatorObserver>[],
    this.builder,
    this.title = '',//--->tag2<---
    this.onGenerateTitle,
    this.color,
    this.theme,//--->tag3<---
    this.locale,
    this.localizationsDelegates,
    this.localeListResolutionCallback,
    this.localeResolutionCallback,
    this.supportedLocales = const <Locale>[Locale('en', 'US')],
    this.debugShowMaterialGrid = false,
    this.showPerformanceOverlay = false,
    this.checkerboardRasterCacheImages = false,
    this.checkerboardOffscreenLayers = false,
    this.showSemanticsDebugger = false,
    this.debugShowCheckedModeBanner = true,

//--->tag1<---[title是個字串]----
/// This value is passed unmodified to [WidgetsApp.title].
final String title;

//--->tag2<---[theme是個ThemeData物件:儲存材料設計主題的顏色和版式值]----
/// The colors to use for the application's widgets.
final ThemeData theme;

//--->tag3<---[home是個Widget物件]----
/// {@macro flutter.widgets.widgetsApp.home}
final Widget home;
複製程式碼

2.Scaffold--腳手架

什麼是腳手架,大概就是這個感覺吧,也就是輔助腳手的工具,方便施工

腳手架.png

PreferredSizeWidget             this.appBar,
Widget                          this.body,
Widget                          this.floatingActionButton,
FloatingActionButtonLocation    this.floatingActionButtonLocation,
FloatingActionButtonAnimator    this.floatingActionButtonAnimator,
List<Widget>                    this.persistentFooterButtons,
Widget                          this.drawer,
Widget                          this.endDrawer,
Widget                          this.bottomNavigationBar,
Widget                          this.bottomSheet,
Color                           this.backgroundColor,
bool                            this.resizeToAvoidBottomPadding = true,
bool                            this.primary = true,
複製程式碼

3:AppBar--App的Bar

就像安卓的ToolBar一樣的控制元件

Widget                  this.leading,
bool                    this.automaticallyImplyLeading = true,
Widget                  this.title,
List<Widget>            this.actions,
Widget                  this.flexibleSpace,
PreferredSizeWidget     this.bottom,
double                  this.elevation = 4.0,
Color                   this.backgroundColor,
Brightness              this.brightness,
IconThemeData           this.iconTheme,
TextTheme               this.textTheme,
bool                    this.primary = true,
bool                    this.centerTitle,
double                  this.titleSpacing = NavigationToolbar.kMiddleSpacing,
double                  this.toolbarOpacity = 1.0,
double                  this.bottomOpacity = 1.0,
複製程式碼

新手任務1:能力小測試

測試.png

MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.lightBlue,
        ),
        home: Scaffold(
            appBar: AppBar(
                title: Text("張風捷特烈"),//標題
                backgroundColor: Color(0xffcbf231), //背景色
                elevation: 12,//陰影
                centerTitle: true,
                toolbarOpacity: .4)//透明度
        ));
複製程式碼
新手任務完成,獎勵卡片:歡迎繼續冒險
- - -
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)

4:Text--文字
 const Text(this.data, {
TextStyle           this.style,
TextAlign           this.textAlign,
TextDirection       this.textDirection,
Locale              this.locale,
bool                this.softWrap,
TextOverflow        this.overflow,
double              this.textScaleFactor,
int                 this.maxLines,
String              this.semanticsLabel,

  /// Creates a text widget with a [TextSpan].
  const Text.rich(this.textSpan, {
        //同上
  })
複製程式碼
//---->[TextStyle]----------------
bool                this.inherit = true,
Color               this.color,
double              this.fontSize,
FontWeight          this.fontWeight,
FontStyle           this.fontStyle,
double              this.letterSpacing,
double              this.wordSpacing,
TextBaseline        this.textBaseline,
double              this.height,
Locale              this.locale,
Paint               this.foreground,
Paint               this.background,
List<ui.Shadow>     this.shadows,
TextDecoration      this.decoration,
Color               this.decorationColor,
TextDecorationStyle this.decorationStyle,
String              this.debugLabel,
String              String fontFamily,

//---->[TextAlign]----------------
enum TextAlign {
  left,right,center,justify,start,end,
}

//---->[TextOverflow]----------------
enum TextOverflow {
  clip,fade,ellipsis,
}
複製程式碼

5.FloatingActionButton--浮動動作按鈕
Widget                  this.child,
String                  this.tooltip,
Color                   this.foregroundColor,
Color                   this.backgroundColor,
Object                  this.heroTag = const _DefaultHeroTag(),
double                  this.elevation = 6.0,
double                  this.highlightElevation = 12.0,
VoidCallback            @required this.onPressed,
bool                    this.mini = false,
ShapeBorder             this.shape = const CircleBorder(),
Clip                    this.clipBehavior = Clip.none,
MaterialTapTargetSize   this.materialTapTargetSize,
bool                    this.isExtended = false,
複製程式碼
6.Icon--圖示
double          this.size,
Color           this.color,
String          this.semanticLabel,------This label does not show in the UI.
TextDirection   this.textDirection,
複製程式碼
新手任務2:

Text

FloatingActionButton.png

body: Text(
            "一簫一劍平生意,負盡狂名十五年",
            maxLines: 1,
            overflow: TextOverflow.fade,
            style: TextStyle(
                color: Colors.blue,
                fontSize: 20,
                letterSpacing: 10,
                fontWeight: FontWeight.bold,
                background: Paint()..color = Colors.amberAccent),
          ),
          floatingActionButton: FloatingActionButton(
            backgroundColor: Colors.deepOrangeAccent,
            elevation: 12,
            highlightElevation: 24,
            onPressed: () {},
            tooltip: 'Increment',
            child: Icon(Icons.add,size: 40,color: Colors.white,semanticLabel:"toly"),
          ),
複製程式碼

三、基礎控制元件點將臺(1)

以上6張卡片是初始專案中的控制元件,通過新手任務基本上更加熟悉了一些
Flutter還有哪些控制元件,建議看一下Flutter中文網,羅列的挺好的,下面一起學習一下
(PS:看了一下,真是多如雞毛...嚇得我不知從何入手)

所謂`打蛇打七寸,擒賊先擒王`,小兵之後再收拾  
通過Android和html+css,我領悟到,對於介面設計者而言,佈局是至關重要的,所以先看容器
複製程式碼
1.Layout佈局容器之Row+Column--行+列

Row和Column.png


1.1:Row的基礎認知
---->[原始碼註釋第一句]-----------------------------
A widget that displays its children in a horizontal array.
一個以水平陣列的形式顯示其子部件的Widget。

 Row({
    Key key,
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    MainAxisSize mainAxisSize = MainAxisSize.max,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    TextDirection textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline textBaseline,
    List<Widget> children = const <Widget>[],
複製程式碼
1.2:基本使用

children看來是一個Widget陣列,想想也不難理解,畢竟做大哥的,當然要有不少小弟啦
注:為了方便修改,以下程式碼把Scaffold的body屬性值抽成變數使用

var row_test = Row(
  children: <Widget>[
    Text('絕域從軍計惘然,,'),
    Text('東南幽恨滿詞箋。'),
    Text('一簫一劍平生意,'),
    Text('負盡狂名十五年。'),
  ],
);
複製程式碼

越界提醒.png

可以看出越界有提醒,感覺蠻有心的,水平排列沒毛病


1.3.Column:用法基本上差不多
---->[原始碼註釋第一句]-----------------------------
 A widget that displays its children in a vertical array.
一個以豎直陣列的形式顯示其子部件的Widget。

Column({
    Key key,
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    MainAxisSize mainAxisSize = MainAxisSize.max,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    TextDirection textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline textBaseline,
    List<Widget> children = const <Widget>[],
複製程式碼
1.4.Column基本使用
var row_column = Column(
  children: <Widget>[
    Text('絕域從軍計惘然,,'),
    Text('東南幽恨滿詞箋。'),
    Text('一簫一劍平生意,'),
    Text('負盡狂名十五年。'),
  ],
);
複製程式碼

Column.png


恭喜完成成就:佈局菜鳥---獎勵卡片:
- - -
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)

恭喜解鎖新卡片:Expanded,快去用用吧
Expanded意思是:使…伸展,看到下面的圖,你應該就會明白

var row_test = Row(
  children: <Widget>[
    Expanded(
      child:Text('絕域從軍計惘然,'),
    ),
    Expanded(
      child:Text('東南幽恨滿詞箋。'),
    ),
    Expanded(
      child:Text('一簫一劍平生意,'),
    ),
    Expanded(
      child:Text('負盡狂名十五年。'),
    ),
  ],
);
複製程式碼

Expanded.png


2.Container--容器

可以理解為Android中的View,更像html中的div
Container是一個沒有狀態的控制元件

Container.png


2.1:原始碼小窺
---->[原始碼註釋第一句]-----------------------------
A convenience widget that combines common painting, positioning, and sizing widgets.
一個方便的widget,它組合了常見的painting、positioning和sizing 控制元件。

Color                   color,
double                  width,
double                  height,
Widget                  this.child,
EdgeInsetsGeometry      this.margin,
EdgeInsetsGeometry      this.padding,
AlignmentGeometry       this.alignment,
Decoration              Decoration decoration,
Decoration              this.foregroundDecoration,
BoxConstraints          BoxConstraints constraints,
Matrix4                 this.transform,
複製程式碼

2.2:簡單使用:

[插曲]這裡分享一個點:當看到一個新的東西應該怎麼辦?

比如`margin`,看到`EdgeInsetsGeometry`我的心情是一臉懵X,不應該是數字嗎?
進原始碼:`abstract class EdgeInsetsGeometry {`,抽象的,找他兒子去,
AndroidStudio中按`Ctrl+H`可以檢視繼承樹,然後就看到了EdgeInsets.fromLTRB
這樣Flutter的margin就和你的知識庫中的margin進行了連線,你就會用了

class EdgeInsets extends EdgeInsetsGeometry {
  const EdgeInsets.fromLTRB(this.left, this.top, this.right, this.bottom);
  const EdgeInsets.all(double value)
      : left = value, top = value, right = value, bottom = value;

新事物往往都與舊事物有聯絡,學習新事物最好快速找到它與你知識庫中舊事物的聯絡,
聯絡的多少取決於你知識庫中內容的多少,連線得越多,你會越快或越能掌握舊事物 
複製程式碼
var container_test = Container(
  color: Color.fromARGB(100, 81, 211, 253),
  height: 100,
  width: 200,
  child: Text("張風捷特烈"),
  margin: EdgeInsets.fromLTRB(5, 10, 15, 20),
  padding:  EdgeInsets.all(40),
);
複製程式碼

padding和margin簡稱pm,左圖是上面程式碼沒有pm時,右圖是有pm時

Container測試.png


恭喜達成成就:Container使用者--卡牌獎勵:
- - -
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)

NPC:恭喜解鎖兩張輔助卡PaddingCenter,快來測試一下吧
這兩個沒什麼好說的,顧圖思義,看圖吧

var padding_test = Container(
  color: Color.fromARGB(100, 81, 211, 253),
  height: 150,
  width: 250,
  child: Padding(
    padding: EdgeInsets.all(10),
    child: Text("張風捷特烈"),
  ),
);


var center_test = Container(
  color: Color.fromARGB(100, 81, 211, 253),
  height: 150,
  width: 250,
  child: Center(
    child: Text("張風捷特烈"),
  ),
);
複製程式碼

Center和Padding.png


3.Stack -- 堆疊

第一反應:棧?有道了一下,有堆疊的意思

---->[原始碼註釋第一句]-----------------------------
A widget that positions its children relative to the edges of its box.
一個相對於它的框的邊緣來定位它的子部件的Widget。

    this.alignment = AlignmentDirectional.topStart,
    this.textDirection,
    this.fit = StackFit.loose,
    this.overflow = Overflow.clip,
    List<Widget> children = const <Widget>[],
    
複製程式碼

觸發新手任務3,並觸發區域性Widget樹,系統贈送卡牌:

看一下Widget樹.png

- - -
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)

請完成下面佈局:

新手任務3.png

var stack_test = Container(
    color: Color.fromARGB(100, 81, 211, 253),
    height: 150,
    width: 250,
    child: Stack(
      alignment: Alignment.centerLeft,
      children: <Widget>[
        Text('絕域從軍計惘然,,'),
        Align(
          alignment: Alignment.topRight,
          widthFactor: 1.5,
          child: Card(
              elevation: 10, color: Color(0xffffffff), child: Text('東南幽恨滿詞箋。')),
        ),
        Text('一簫一劍平生意,'),
        Text('負盡狂名十五年。'),
      ],
    ));
複製程式碼

現在對Stack有點感覺了吧,它像FramLayout一樣會疊合控制元件,
並且alignment還可以確定Stack自身相對於老爸的位置
Align也有alignment,不過能有一個孩子,Card我最喜歡了
這裡mark一下Card裡的ShapeBorder shape,原始碼粗略看了一下,可能挺好玩,今天主看控制元件


4.IndexedStack--定索引顯示

按照索引來顯示堆疊容器中的控制元件,挺好玩的

看一下Widget樹2.png

IndexedStack.png

var index_stack_test = Container(
    color: Color.fromARGB(100, 81, 211, 253),
    height: 150,
    width: 250,
    child: IndexedStack(
      index:3,
      alignment: Alignment.centerLeft,
      children: <Widget>[
        Text('絕域從軍計惘然,'),
        Align(
          alignment: Alignment.topRight,
          widthFactor: 1.5,
          child: Card(
              elevation: 10, color: Color(0xffffffff), child: Text('東南幽恨滿詞箋。')),
        ),
        Text('一簫一劍平生意,'),
        Text('負盡狂名十五年。'),
      ],
    ));

複製程式碼

5.Transform--變換

transform屬性的Matrix4有機會肯定好好分析分析,mark一下
Matrix4.rotationZ傳入的是弧度制的度數,佩服佩服

Transform(
    origin: Offset(0, 150),
    transform: Matrix4.rotationZ(3.1415 / 4),
    child: //同上面的Container,挺長的,不貼了
    )
複製程式碼

Transform.png


6.Offstage--顯隱控制

負盡狂名十五年用Offstage包裹一下,offstage為true--隱藏,為false--顯示
感覺應該挺好用,簡潔,明瞭,人狠話不多。

Offstage(
    offstage: false,
    child: Text('負盡狂名十五年。'),
),
複製程式碼
恭喜獲得成就:佈局小新手 :獎勵卡牌:
- - -
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)

三、基礎控制元件點將臺之--三大戰力

隱藏劇情觸發:
NPC:傳說有三條惡龍盤踞在佈局深處,為禍人間,勇士們,準備好了嗎?

看一下Widget樹3.png

1.表格--Table
1.1:屬性一覽
    this.children = const <TableRow>[],
    this.columnWidths,
    this.defaultColumnWidth = const FlexColumnWidth(1.0),
    this.textDirection,
    this.border,
    this.defaultVerticalAlignment = TableCellVerticalAlignment.top,
    this.textBaseline,
複製程式碼

1.2:新手任務4:完成下面表格

表格.png

程式碼實現:
columnWidths:可以指定每列的寬度
border:邊線的樣式
children:通過TableRow來顯示一行

var table_test = Table(
  columnWidths: const <int, TableColumnWidth>{
    0: FixedColumnWidth(60.0),
    1: FixedColumnWidth(100.0),
    2: FixedColumnWidth(100.0),
    3: FixedColumnWidth(80.0),
  },
  defaultVerticalAlignment: TableCellVerticalAlignment.middle,
  border:
      TableBorder.all(color: Color(0xff16DAF1), width: 1.0, style: BorderStyle.solid),
  children: const <TableRow>[
    TableRow(
      children: <Widget>[
        Center(child: Text('姓名')),
        Center(child: Text('年齡')),
        Center(child: Text('稱號')),
        Center(child: Text('武器')),
      ],
    ),
    TableRow(
      children: <Widget>[
        Text('捷特'),
        Text('24'),
        Text('風神'),
        Text('黑風劍'),
      ],
    ),
    TableRow(
      children: <Widget>[
        Text('巫纓'),
        Text('23'),
        Text('百里巫纓'),
        Text('百里弓'),
      ],
    ),
    TableRow(
      children: <Widget>[
        Text('龍少'),
        Text('23'),
        Text('控尊'),
        Text('控尊戒'),
      ],
    ),
  ],
);
複製程式碼

2.流動容器 --Flow:
2.1:屬性一覽

屬性很簡潔,但是:FlowDelegate夠熬一碗粥的

FlowDelegate @required this.delegate,
List<Widget> children = const <Widget>[],
複製程式碼

2.2:新手任務5:用完Flow成下面佈局

簡單分析一下:隨機顏色,隨機長度,到尾部不夠就換行

flow.png

程式碼實現:從網上找了一個FlowDelegate的實現類
核心就是根據位置可以自己繪製孩子的位置(吐槽:原始碼了竟然沒有實現類,給一個也好啊...)

class MarginFlowDelegate extends FlowDelegate {
  EdgeInsets _margin = EdgeInsets.zero;//成員變數_margin
  MarginFlowDelegate(this._margin); //建構函式
  @override//繪製孩子的方法
  void paintChildren(FlowPaintingContext context) {
    var offsetX = _margin.left;
    var offsetY = _margin.top;
    for (int i = 0; i < context.childCount; i++) {
      var w = context.getChildSize(i).width + offsetX + _margin.right;
      if (w < context.size.width) {
        context.paintChild(i, transform: new Matrix4.translationValues(offsetX, offsetY, 0.0));
        offsetX = w + _margin.left;
      } else {
        offsetX = _margin.left;
        offsetY += context.getChildSize(i).height + _margin.top + _margin.bottom;
        context.paintChild(i,transform: new Matrix4.translationValues(offsetX, offsetY, 0.0));
        offsetX += context.getChildSize(i).width + _margin.left + _margin.right;
      }
    }
  }
複製程式碼

動態生成Widget陣列(可別傻傻的cv,60個Container)

formColorList(int count) {
  var random = new Random();
  var li = <Widget>[];

  for (int i = 0; i < count; i++) {
    li.add(new Container(
      width: 100 * (random.nextDouble() + 0.3),
      height: 30,
      color: randomRGB(),
    ));
  }
  return li;
}
複製程式碼

用起來倒是簡單:

var flow_test = Flow(
    delegate: MarginFlowDelegate(EdgeInsets.all(5)),
    children: formColorList(60));
複製程式碼

3.包裹--Warp
3.1:簡單認識:

這東西和css的flex有九分相似,還好我flex佈局玩的挺好:有興趣的可看這裡
Flow用起來麻煩很多,但可控制,靈活性更好,如果不是什麼逆天改命的佈局,Warp應該夠了

  Wrap({
    Key key,
    this.direction = Axis.horizontal,
    this.alignment = WrapAlignment.start,
    this.spacing = 0.0,
    this.runAlignment = WrapAlignment.start,
    this.runSpacing = 0.0,
    this.crossAxisAlignment = WrapCrossAlignment.start,
    this.textDirection,
    this.verticalDirection = VerticalDirection.down,
    List<Widget> children = const <Widget>[],
  }) 
複製程式碼
direction

方向.png


3.2:新手任務6-1

新手任務6-1.png

var wrap_test = Wrap(
    spacing: 8.0, // 列間距
    runSpacing: 4.0, //行間距
    direction:Axis.vertical ,
    crossAxisAlignment:WrapCrossAlignment.center,
    children: formColorList(50));
複製程式碼

3.3:新手任務6-2

新手任務7.png

var wrap_test = Wrap(
    spacing: 8.0, // 列間距
    runSpacing: 4.0, //行間距
    direction:Axis.horizontal ,
    alignment:WrapAlignment.spaceBetween,
    children: formColorList(50));
複製程式碼
duang,三大戰力倒下,恭喜獲得稱號:佈局勇士,收穫三張傳說級卡片:
- - -
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)

三、基礎控制元件點將臺之--列表

NPC:好吧,我編不下去了...大家加油!

看一下Widget樹4.png


1.老夥伴:ListView

這裡先簡單看一下效果,明天根據例子來詳細分析具體用法
ListView,單獨可以用,傳入一個Widget陣列,批量生產ListView.builder簡潔些

  ListView.builder({
    Key key,
    Axis scrollDirection = Axis.vertical,
    bool reverse = false,
    ScrollController controller,
    bool primary,
    ScrollPhysics physics,
    bool shrinkWrap = false,
    EdgeInsetsGeometry padding,
    this.itemExtent,
    @required IndexedWidgetBuilder itemBuilder,
    int itemCount,
    bool addAutomaticKeepAlives = true,
    bool addRepaintBoundaries = true,
    bool addSemanticIndexes = true,
    double cacheExtent,
    int semanticChildCount,
複製程式碼

豎直 水平
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
//豎直
var list_view_test = ListView.builder(
  itemCount: 20,
  padding: EdgeInsets.all(8.0),
  itemExtent: 60.0,
  itemBuilder: (BuildContext context, int index) {
    return Card(
      child: Center(child: Text('toly $index')),
    );
  },
);

//水平
var list_view_test = ListView.builder(
  itemCount: 20,
  padding: EdgeInsets.all(8.0),
  scrollDirection:Axis.horizontal,
  itemExtent: 60.0,
  itemBuilder: (BuildContext context, int index) {
    return Card(
      child: Center(child: Text('toly $index')),
    );
  },
);

複製程式碼

2--老夥伴:GridView
GridView.count({
    Key key,
    Axis scrollDirection = Axis.vertical,
    bool reverse = false,
    ScrollController controller,
    bool primary,
    ScrollPhysics physics,
    bool shrinkWrap = false,
    EdgeInsetsGeometry padding,
    @required int crossAxisCount,
    double mainAxisSpacing = 0.0,
    double crossAxisSpacing = 0.0,
    double childAspectRatio = 1.0,
    bool addAutomaticKeepAlives = true,
    bool addRepaintBoundaries = true,
    bool addSemanticIndexes = true,
    double cacheExtent,
    List<Widget> children = const <Widget>[],
    int semanticChildCount,
複製程式碼

水平GridView 豎直GridView
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
//豎直GridView
var grid_view_test = GridView.count(
  crossAxisCount: 4,
  children: List.generate(
    100,
    (index) {
      return  Card(
        child: Center(child: Text('toly $index')),
      );
    },
  ),
);

//水平GridView
var grid_view_test = GridView.count(
  crossAxisCount: 4,
  scrollDirection:Axis.horizontal,
  children: List.generate(
    100,
    (index) {
      return  Card(
        child: Center(child: Text('toly $index')),
      );
    },
  ),
);

複製程式碼

3.軸列容器--ListBody(我自己取的名字)

好吧,被它的名字騙了,和ListView並沒有太大的關係,也就是個多孩子的容器
優點在於在指定軸上尺寸正常,另一軸上會被拉伸,見圖:

A widget that arranges its children sequentially along a given axis,
forcing them to the dimension of the parent in the other axis.
一個widget,它按照給定的軸順序排列它的子部件,並迫使它們位於另一個軸上的父軸的維度。


ListBody({
    Key key,
    this.mainAxis = Axis.vertical,
    this.reverse = false,
    List<Widget> children = const <Widget>[],
複製程式碼

水平定 豎直定
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
//豎直定
var list_body_test = Column(
  children: <Widget>[
    ListBody(
      mainAxis: Axis.vertical,
      reverse: false,
      children: formColorList(5)
    )],
);

//水平定
var list_body_test = Row(
  children: <Widget>[
    ListBody(
      mainAxis: Axis.horizontal,
      reverse: false,
      children: formColorList(5)
    )],
);

複製程式碼
好了,又到三局一度的髮卡時間了

未精煉的傳說級卡片,更多屬性加成,戰士們,去精煉吧

- - -
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)

四、容器掃個尾:

1.Baseline

將文字按照基線對齊(因為比較好看)--baseline越大,距離頂端越遠

Baseline.png

  const Baseline({
    Key key,
    @required this.baseline,
    @required this.baselineType,
    Widget child
複製程式碼

formTextList(int count) {
  var random = new Random();
  var li = <Widget>[];

  for (int i = 0; i < count; i++) {
    li.add(new Baseline(
      baselineType: TextBaseline.alphabetic,
      child: new Text('Toly',
        style: new TextStyle(
          fontSize: 20.0 + random.nextInt(40),
          textBaseline: TextBaseline.alphabetic,
        ),
      ),
      baseline: 80,
    ));
  }
  return li;
}

var base_line_test = new Row(
  children: formTextList(5),
);
複製程式碼

2.FractionallySizedBox

這個挺有意思,兒子隨爺爺,父親(FractionallySizedBox)中間倒把手
可以實現爺爺和孫子之間的尺寸比例聯絡

  const FractionallySizedBox({
    Key key,
    this.alignment = Alignment.center,
    this.widthFactor,
    this.heightFactor,
    Widget child,
複製程式碼

FractionallySizedBox測試.png

var fsb_test = new Container(
  color: Colors.blue,
  height: 150.0,
  width: 150.0,
  child: new FractionallySizedBox(
    alignment: Alignment.bottomCenter,
    widthFactor: 1.5,
    heightFactor: 0.5,
    child: new Container(
      color: Colors.red,
    ),
  ),
);
複製程式碼

3.AspectRatio

就是設定一個定比例的容器width/height=aspectRatio

  const AspectRatio({
    Key key,
    @required this.aspectRatio,
    Widget child
複製程式碼

AspectRatio測試.png

var aspectratio_test = new Container(
  width: 200.0,
  child: new AspectRatio(
    aspectRatio: 1.5,
    child: new Container(
      color: Colors.red,
    ),
  ),
);
複製程式碼

恭喜獲得稱號:佈局學徒 ,獎勵卡片
- - -
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)
Flutter第3天--基礎控制元件(上)

還剩幾個Box,明天寫幾個佈局例子順帶講一下,反正每個新控制元件都會發張卡
最後把卡片總結起來,看看能不能湊夠兩幅撲克牌...列印出來當撲克牌打,還怕Flutter控制元件學不會?
好了,今天就到這裡,腦細胞死不少,趕快看幾集動漫補補腦。


五、總結一下mark的點:

//第一天:
3.現在焦點應該匯聚在StatefulWidget身上,很多地方都出現了,mark一下
---StatefulWidget是Widget的一個子類,是具有狀態的控制元件,可謂元老級別

4.canvas竟然沒辦法畫文字,這不科學,mark一下
---保持mark

//第三天:
1.這裡mark一下Card裡的ShapeBorder shape,原始碼粗略看了一下,可能挺好玩,今天主看控制元件
---保持mark

2.transform屬性的Matrix4有機會肯定好好分析分析,mark一下
---保持mark
複製程式碼

後記:捷文規範

1.本文成長記錄及勘誤表
專案原始碼 日期 備註
V0.1-github 2018-12-18 Flutter第3天--基礎控制元件(上)
2.更多關於我
筆名 QQ 微信 愛好
張風捷特烈 1981462002 zdl1994328 語言
我的github 我的簡書 我的掘金 個人網站
3.宣告

1----本文由張風捷特烈原創,轉載請註明
2----歡迎廣大程式設計愛好者共同交流
3----個人能力有限,如有不正之處歡迎大家批評指證,必定虛心改正
4----看到這裡,我在此感謝你的喜歡與支援


icon_wx_200.png

相關文章