7. Flutter - 基礎組件 之 布局Widget

1. Align組件

  const Align({
    Key key,
    // 對齊方式
    this.alignment = Alignment.center,
    // 寬度因子,不設置的情況,會盡可能大
    this.widthFactor,
    // 高度因子,不設置的情況,會盡可能大
    this.heightFactor,
    // 要布局的子Widget
    Widget child,
  })
Alignment對齊方式設置

文檔中已經為我們定義了一些常量:如下

  static const Alignment topLeft = Alignment(-1.0, -1.0);
  /// The center point along the top edge.
  static const Alignment topCenter = Alignment(0.0, -1.0);
  /// The top right corner.
  static const Alignment topRight = Alignment(1.0, -1.0);
  /// The center point along the left edge.
  static const Alignment centerLeft = Alignment(-1.0, 0.0);
  /// The center point, both horizontally and vertically.
  static const Alignment center = Alignment(0.0, 0.0);
  /// The center point along the right edge.
  static const Alignment centerRight = Alignment(1.0, 0.0);
  /// The bottom left corner.
  static const Alignment bottomLeft = Alignment(-1.0, 1.0);
  /// The center point along the bottom edge.
  static const Alignment bottomCenter = Alignment(0.0, 1.0);
  /// The bottom right corner.
  static const Alignment bottomRight = Alignment(1.0, 1.0);

centerAlignment(0.0, 0.0),topLeftAlignment(-1.0, -1.0),這些值均是以父視圖為準進行的設置。父視圖范圍內取值為(-1.0, -1.0) ~ (1.0, 1.0),中心點為(0.0, 0.0)。當然我們也可以取值(0, 2),(3,0)等,這不過會超出父視圖顯示范圍。

widthFactor和heightFactor作用
  • 子組件在父組件中的對齊方式必須有一個前提,就是父組件得知道自己的范圍(寬度和高度);
  • 如果widthFactor和heightFactor不設置,那么默認Align會盡可能的大(盡可能占據自己所在的父組件);
  • 我們也可以對他們進行設置,比如widthFactor設置為5,那么相對于Align的寬度是子組件跨度的5倍;
  • 代碼演示:

ps:Container為容器視圖,主要為了設置背景色及大小,方便觀察,后面會有介紹。

class AlignTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          margin: EdgeInsets.all(20),
          color: Colors.blue,
          child: Align(
            child: Icon(Icons.pets, size: 36, color: Colors.red),
            //左上
            alignment: Alignment(-1, -1),
            widthFactor: 5,
            heightFactor: 5,
          ),
        ),
        Container(
          padding: EdgeInsets.all(10),
          color: Colors.green,
          child: Align(
            child: Icon(Icons.pets, size: 36, color: Colors.red),
            //右下角
            alignment: Alignment(1, 1),
            widthFactor: 3,
            heightFactor: 3,
          ),
        )
      ],
    );
  }
}
  • 顯示效果:


    Align效果演示.png

2. Center 組件

class Center extends Align {
  const Center({ 
      Key key, 
      double widthFactor, 
      double heightFactor, 
      Widget child 
  }) : super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
}

Center組件繼承自Align,只是將alignment設置為Alignment.center,且Alignalignment屬性默認為 Alignment.center,
所以其實Align(alignment = Alignment.center)可以與 Center相互替換,效果是一樣的。

3. Padding組件

Padding在其他端也是一個屬性而已,但是在Flutter中是一個Widget,但是Flutter中沒有Margin這樣一個Widget,這是因為外邊距也可以通過Padding來完成。
Padding通常用于設置子Widget到父Widget的邊距(你可以稱之為是父組件的內邊距或子Widget的外邊距)。

  • 代碼演示:
class PaddingTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 300,
      height: 300,
      color: Colors.green,
      child: Padding(
        padding: EdgeInsets.all(20),
        child: Container(
            decoration: BoxDecoration(
                color: Colors.blue,
                border: Border.all(color: Colors.red, width: 3)),
            child: Text('測試')),
      ),
    );
  }
}

如下圖,Padding的設置對于綠色視圖,相當于內邊距;而對于藍色視圖則是外邊距。

顯示效果

4. Container 組件

Container組件類似于iOS中的UIView,主要負責視圖的承載,可以通過它設置背景色、邊框、圓角等等。

Container({
  Key key,
  //AlignmentGeometry類型可選命名參數,容器內子Widget如何對其,使用其子類Alignment
  this.alignment,
  //EdgeInsetsGeometry類型可選命名參數,設置容器內邊距
  this.padding,
  //Color類型可選命名參數,容器填充色
  Color color,
  //Decoration類型可選命名參數,繪制在child子Widget后面的裝飾,使用BoxDecoration
  Decoration decoration,
  //Decoration類型可選命名參數,繪制在child子Widget前面的裝飾,使用BoxDecoration
  this.foregroundDecoration,
  //double類型可選命名參數,容器的寬度
  double width,
  //double類型可選命名參數,容器的高度
  double height,
  //BoxConstraints類型可選命名參數,對child設置的Widget的約束
  BoxConstraints constraints,
  //EdgeInsetsGeometry類型可選命名參數,設置容器外邊距
  this.margin,
  //Matrix4類型可選命名參數,在繪制容器之前要應用的轉換矩陣
  this.transform,
  //Widget類型可選命名參數,容器包含的子Widget
  this.child,
})

容器的大小可以通過width、height屬性來指定,也可以通過constraints來指定,如果同時存在時,width、height優(yōu)先。實際上Container內部會根據width、height來生成一個constraints;
colordecoration是互斥的,不可同時設置。

  • BoxDecoration

Container有一個非常重要的屬性 decoration,他對應的類型是Decoration類型,但是它是一個抽象類。
在實際開發(fā)中,我們經常使用它的實現(xiàn)類BoxDecoration來進行實例化。

const BoxDecoration({
  //Color類型可選命名參數,填充背景色
  this.color,
  //DecorationImage類型可選命名參數,在背景或漸變上繪制的圖像
  this.image,
  //BoxBorder類型可選命名參數,邊框設置
  this.border,
  //BorderRadiusGeometry類型可選命名參數,設置圓角
  this.borderRadius,
  //List<BoxShadow>類型可選命名參數,盒子后面的盒子投射的陰影列表
  this.boxShadow,
  //Gradient類型可選命名參數,填充框時使用的漸變
  this.gradient,
  //BlendMode類型可選命名參數,應用于框的顏色或漸變背景的混合模式
  this.backgroundBlendMode,
  //BoxShape類型可選命名參數,將背景顏色、漸變和圖像填充到并作為boxShadow投射的形狀
  this.shape = BoxShape.rectangle,
})
示例代碼:
class ContainerTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      // width: 400,
      // height: 400,
      padding: EdgeInsets.all(20),

      color: Colors.lightBlue,
      child: Container(
          width: 280,
          height: 280,
          //內邊距
          // padding: EdgeInsets.all(100),
          //外邊距
          // margin: EdgeInsets.all(80),
          // 不可與 decoration 同時設置
          // color: Colors.red,
          //變形:旋轉
          transform: Matrix4.rotationZ(0.1),
          //裝飾:設置顏色。漸變色、形狀、陰影等。
          decoration: BoxDecoration(
              color: Colors.green,
              //漸變
              gradient: LinearGradient(
                  colors: [Colors.blue, Colors.red, Colors.green]),
              //形狀
              shape: BoxShape.circle,
              //陰影
              boxShadow: [
                BoxShadow(offset: Offset(10, 10), color: Colors.grey)
              ],
              backgroundBlendMode: BlendMode.srcOver,
              border: Border.all(color: Colors.orange, width: 5)),
          child: Icon(
            Icons.people,
            color: Colors.orange,
            size: 100,
          )),
    );
  }
}
顯示效果.png

5. Flex組件

Row組件和Column組件都繼承自Flex組件。
Flex組件和Row、Column屬性主要的區(qū)別就是多一個direction。
direction的值為Axis.horizontal的時候,則是Row
direction的值為Axis.vertical的時候,則是Column。

  • 5.1 Row組件
 Row({
    Key key,
    //主軸對齊方式
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    //主軸大小(水平方向盡可能大)
    MainAxisSize mainAxisSize = MainAxisSize.max,
    //    交叉處對齊方式
    CrossAxisAlignment crossAxisAlignment =  CrossAxisAlignment.center,
     //   水平方向子widget布局順序
    TextDirection textDirection,
     //表示Row縱軸(垂直)的對齊方向
    VerticalDirection verticalDirection = VerticalDirection.down,
    //    如果上面是baseline對齊方式
    TextBaseline textBaseline = TextBaseline.alphabetic,
    // 子widget列表
    List<Widget> children = const <Widget>[],
  })
  • mainAxisSize:表示Row在主軸(水平)方向占用的空間,默認是MainAxisSize.max,Row的寬度始終等于水平方向的最大寬度
    MainAxisSize.min表示盡可能少的占用水平空間,Row的實際寬度等于所有子widgets占用的的水平空間;
  • mainAxisAlignment:表示子Widgets在Row所占用的水平空間內對齊方式
    如果mainAxisSize值為MainAxisSize.min,則此屬性無意義,因為子widgets的寬度等于Row的寬度
    只有當mainAxisSize的值為MainAxisSize.max時,此屬性才有意義
    MainAxisAlignment.start表示沿textDirection的初始方向對齊,
    如textDirection取值為TextDirection.ltr時,則MainAxisAlignment.start表示左對齊,textDirection取值為TextDirection.rtl時表示從右對齊。
    而MainAxisAlignment.end和MainAxisAlignment.start正好相反;
    MainAxisAlignment.center表示居中對齊。
  • crossAxisAlignment:表示子Widgets在縱軸方向的對齊方式
    Row的高度等于子Widgets中最高的子元素高度
    它的取值和MainAxisAlignment一樣(包含start、end、 center三個值)
    不同的是crossAxisAlignment的參考系是verticalDirection,即verticalDirection值為VerticalDirection.down時crossAxisAlignment.start指頂部對齊,verticalDirection值為VerticalDirection.up時,crossAxisAlignment.start指底部對齊;而crossAxisAlignment.end和crossAxisAlignment.start正好相反;
5.2 Column組件

Column組件與 Row組件使用方式完全一致,只是方向不同而已。

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>[],
  })
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容