flutter widget組件之-----------佈局組件(單個子元素)

flutter widget組件之-----------佈局組件(單個子元素)

widget分爲兩類:widgets library中的標準widget和Material Components library中的專用widget;任何應用程序都可以使用widgets library中的widget,但只有Material應用程序可以使用Material Components庫。其中Card,ListTitle就是Material Components庫中的組件。

Container

一個擁有繪製、定位、調整大小的 widget

  • 構造函數
Container({
    Key key,
    this.alignment,// 對齊方式
    this.padding,// 內邊距
    Color color,// 背景色
    Decoration decoration,// 主體內容裝飾器
    this.foregroundDecoration,// 前景裝飾器
    double width,// 容器寬
    double height,// 容器高
    BoxConstraints constraints,// 應用於子組件的條件約束
    this.margin,// 外邊距
    this.transform,// 轉換
    this.child,// 子組件
  })

  • 應用示例
class MyStatePageState extends State<MyStatePage> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          
          children: <Widget>[
            new Container(
              // color: Colors.red, // 裝飾器的簡單寫,與裝飾器不能共存
              // 條件約束,
              constraints: new BoxConstraints.expand(
                height:
                    Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0,
              ),
              // 裝飾器 給容器添加的樣式
              decoration: new BoxDecoration(
                border: new Border.all(width: 2.0, color: Colors.red),
                color: Colors.grey,
                borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
                image: new DecorationImage(
                  image: new NetworkImage(
                      'http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
                  centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),
                ),
              ),
              padding: const EdgeInsets.all(8.0),// 內邊距 都爲8
              alignment: Alignment.center,// 居中對齊
              // 子組件 
              child: new Text('Hello World',
                  style: Theme
                      .of(context)
                      .textTheme
                      .display1
                      .copyWith(color: Colors.black)),
              // 繞着z軸旋轉 多少弧度
              transform: new Matrix4.rotationZ(0.3),
          ),
        
          ],
        ),
      ),
    );
  }
}

Padding

一個widget, 會給其子widget添加指定的填充

  • 構造函數
Padding({
    Key key,
    @required this.padding,// 內邊距
    Widget child,// 子組件
  })
  • 應用示例
class MyStatePageState extends State<MyStatePage> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
            new Padding(
              // 內邊距
              padding: const EdgeInsets.fromLTRB(20.0, 50.0, 40.0, 40.0),
              // 子組件
              child: new Text("Padding"),
            )
        
          ],
        ),
      ),
    );
  }
}

Center Align

Align:一個widget,它可以將其子widget對齊,並可以根據子widget的大小自動調整大小。
Center:將其子widget居中顯示在自身內部的widget,繼承了Align

  • 構造函數
Align({
    Key key,
    this.alignment = Alignment.center,// 對齊方式
    this.widthFactor,//大於等於1.0的正數,用於計算此組件的寬度,子組件的寬度乘以此寬度因子
    this.heightFactor,//大於等於1.0的正數,用於計算此組件的高度,子組件的寬度乘以此高度因子
    Widget child // 子組件
  })
Center({ 
  Key key, 
  double widthFactor, //大於等於1.0的正數,用於計算此組件的寬度,子組件的寬度乘以此寬度因子
  double heightFactor, //大於等於1.0的正數,用於計算此組件的高度,子組件的寬度乘以此高度因子
  Widget child // 子組件
})

  • 應用示例
class MyStatePageState extends State<MyStatePage> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
           new Center(
             widthFactor: 1.2,// 寬度因子
             heightFactor: 2,// 高度因子
             // 子組件
             child: new Text("Center"),
            ),
            Align(
              // 對齊方式,1.0表示最右邊的邊,0表示中心 ,-1表示最左邊的邊 
              alignment: const Alignment(1.0, 0),
              widthFactor: 3.0, // 寬度因子
              heightFactor: 3.0,// 高度因子
              // 子組件
              child: new Container(
                child: new Text("Align"),
                color: Colors.amber,
              ),
            ),
        
          ],
        ),
      ),
    );
  }
}

FittedBox

按自己的大小調整其子widget的大小和位置。

  • 構造函數
 FittedBox({
    Key key,
    this.fit = BoxFit.contain,// 子項如何填充佈局空間, contain cover等
    this.alignment = Alignment.center,// 對齊方式
    Widget child,//子項
  })
  • 應用示例
class MyStatePageState extends State<MyStatePage> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
             new Container(
              color: Colors.amberAccent,
              alignment: Alignment.center,
              width: double.infinity,
              height: double.infinity,
              // fittedbox
              child: new FittedBox(
                fit: BoxFit.fill,// 通過子項長寬比率來填充
                alignment: Alignment.center,// 居中
                // 子項
                child: new Container(
                  color: Colors.red,
                  child: new Text(
                    "BoxFit.fill",
                    style: const TextStyle(fontSize: 20.0),
                  ),
                ),
              ),
            ),
           
        
          ],
        ),
      ),
    );
  }
}

AspectRatio

一個widget,試圖將子widget的大小指定爲某個特定的長寬比。

  • 構造函數
 AspectRatio({
    Key key,
    @required this.aspectRatio, // 長寬比率,不能爲空
    Widget child // 子組件
  })
  • 應用示例
class MyStatePageState extends State<MyStatePage> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
            new Container(
              height: 200.0,
              // aspectRatio佈局  
              child: new AspectRatio(
                aspectRatio: 2,// 長款比率
                //子組件
                child: new Container(
                  color: Colors.red,
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

ConstrainedBox

對其子項施加附加約束的widget

  • 構造函數
ConstrainedBox({
    Key key,
    @required this.constraints,// 子組件佈局的約束條件
    Widget child // 子組件
  })

  • 應用示例
class MyStatePageState extends State<MyStatePage> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
            new ConstrainedBox(
              // 約束條件  限制的最小、最大長度和寬度
              constraints: const BoxConstraints(
                minWidth: 50.0,
                minHeight: 50.0,
                maxWidth: 150.0,
                maxHeight: 150.0,
              ),
              // 子組件
              child: new Container(
                width: 20.0,
                height: 20.0,
                color: Colors.green,
              ),
            )
           
        
          ],
        ),
      ),
    );
  }
}


Baseline

根據子項的基線對它們的位置進行定位的widget。

  • 構造函數
Baseline({
    Key key,
    @required this.baseline,// 此組件頂部開始放置子組件的邏輯像素數
    @required this.baselineType,// 基線類型 一個TextBaseline類型的實例 enum 
    Widget child // 子組件
  })
  TextBaseline {
  ///對齊字母字符底部的水平線
  alphabetic,

  ///對齊表意字符的水平線
  ideographic,
}

  • 應用示例
class MyStatePageState extends State<MyStatePage> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
          new Baseline(
            baseline: 50.0,//// 此組件頂部開始放置子組件的邏輯像素數
            ///基線類型   對齊字母字符底部的水平線
            baselineType: TextBaseline.alphabetic,
            child: new Text(
              'TjTjTj',
              style: new TextStyle(
                fontSize: 16.0,
                textBaseline: TextBaseline.alphabetic,
              ),
            ),
          ),
          new Baseline(
            baseline: 50.0,
            baselineType: TextBaseline.alphabetic,
            child: new Container(
              width: 30.0,
              height: 30.0,
              color: Colors.red,
            ),
          ),
          new Baseline(
            baseline: 50.0,
            baselineType: TextBaseline.alphabetic,
            child: new Text(
              'RyRyRy',
              style: new TextStyle(
                fontSize: 35.0,
              ),
            ),
          ),
          ],
        ),
      ),
    );
  }
}

FractionallySizedBox

一個widget,它把它的子項放在可用空間的一小部分。關於佈局算法的更多細節,見RenderFractionallySizedOverflowBox。

  • 構造函數
 FractionallySizedBox({
    Key key,
    this.alignment = Alignment.center, // 對齊方式
    this.widthFactor, // widthFactor >= 0.0用於計算此組件的寬度,子組件的寬度乘以此寬度因子
    this.heightFactor,//  heightFactor >= 0.0 用於計算此組件的高度,子組件的高度乘以此高度因子
    Widget child, // 子組件
  })

  • 應用示例
class MyStatePageState extends State<MyStatePage> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
            new Container(
              color: Colors.blue,
              height: 150.0,
              width: 150.0,
              //padding: const EdgeInsets.all(10.0),
              child: new FractionallySizedBox(
                alignment: Alignment.topLeft,// 坐上頂點對齊
                widthFactor: 0.5,// 0.5倍的寬
                heightFactor: 0.5,// 0.5倍的高
                // 子組件
                child: new Container(
                  color: Colors.red,
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

IntrinsicHeight IntrinsicWidget

IntrinsicHeight: 一個widget,它將它的子widget的高度調整其本身實際的高度。
IntrinsicWidget: 一個widget,它將它的子widget的寬度調整其本身實際的寬度

  • 構造函數
IntrinsicHeight({ 
  Key key, 
  Widget child  // 子組件
}) 
IntrinsicWidth({ 
  Key key, 
  this.stepWidth, // 子組件的寬度:n*stepWidth
  this.stepHeight,  // 子組件的高度:n*stepHeight
  Widget child  // 子組件
})

  • 應用示例
class MyStatePageState extends State<MyStatePage> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
            new IntrinsicHeight(
              // 子組件
              child: new Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                // 子組件的高度,自動增加到與下面黃色container同高
                children: <Widget>[
                  new Container(color: Colors.blue, width: 100.0),
                  new Container(color: Colors.red, width: 50.0,height: 50.0,),
                  new Container(color: Colors.yellow, width: 150.0,height: 100,),
                ],
              ),
            ),
            Divider(height: 10,color: Colors.black,),

            new IntrinsicWidth(
              stepHeight: 50.0,
              stepWidth: 40.0, // 子組件的寬度是此值得n倍,此處爲4倍,也就是160,因此。藍色、黃色container的寬度就會自適應到160
              child: new Column(
                children: <Widget>[
                  new Container(color: Colors.blue, height: 100.0),
                  new Container(color: Colors.red, width: 130.0, height: 100.0),
                  new Container(color: Colors.yellow, height: 150.0,),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

LimitedBox

一個當其自身不受約束時才限制其大小的盒子。

  • 構造函數
LimitedBox({
    Key key,
    this.maxWidth = double.infinity,// 沒有BoxConstraints.maxWidth約束的情況下的最大寬度約束
    this.maxHeight = double.infinity,// 沒有BoxConstraints.maxHeight約束的情況下的最大高度約束
    Widget child,// 子組件
  })

  • 應用示例
class MyStatePageState extends State<MyStatePage> {
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
            Container(
              color: Colors.red,
              height: 100,
              width: 250.0,
            ),
            LimitedBox(
              maxWidth: 100.0, // 沒有作用??
              maxHeight: 50, // 最大高度
              child: Container(
                color: Colors.blue,
                height: 100,
                width: 250.0,
              ),
            )
           

            
           
        
          ],
        ),
      ),
    );
  }
}

offstage

一個佈局widget,可以控制其子widget的顯示和隱藏。

  • 構造函數
Offstage({ 
  Key key, 
  this.offstage = true, // 控制子組件的顯示與隱藏,true爲隱藏,false爲顯示
  Widget child // 子組件
})

  • 應用示例
class MyStatePageState extends State<MyStatePage> {
  bool offstage;

  @override
  void initState() {
    super.initState();
    offstage = false;
  }
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
            new Offstage(
              offstage: offstage, // // 控制子組件的顯示與隱藏,true爲隱藏,false爲顯示
              child: Container(color: Colors.blue, height: 100.0),
            ),
            new CupertinoButton(
              child: Text("點擊切換顯示"),
              onPressed: () {
                setState(() {
                  offstage = !offstage;
                });
              },
            )
          ],
        ),
      ),
    );
  }
}

SizedBox OverflowBox SizedOverflowBox

SizedBox:一個特定大小的盒子。這個widget強制它的孩子有一個特定的寬度和高度。如果寬度或高度爲NULL,則此widget將調整自身大小以匹配該維度中的孩子的大小。
OverflowBox: 對其子項施加不同約束的widget,它可能允許子項溢出父級
SizedOverflowBox: 一個特定大小的widget,但是會將它的原始約束傳遞給它的孩子,它可能會溢出

  • 構造函數
SizedBox({ 
  Key key, 
  this.width, // 強制設置子組件的寬度,設置此值後,子組件的寬度將無效
  this.height, // 強制設置子組件的高度,設置此值後,子組件的寬度將無效
  Widget child // 子組件
})
OverflowBox({
    Key key,
    this.alignment = Alignment.center,// 對齊方式
    this.minWidth,// 最小寬度
    this.maxWidth,// 最大寬度
    this.minHeight,// 最小高度
    this.maxHeight,// 最大高度
    Widget child,
})
SizedOverflowBox({
    Key key,
    @required this.size, // 組件大小設置
    this.alignment = Alignment.center,// 對齊方式
    Widget child, // 子組件
})
   

  • 應用示例
class MyStatePageState extends State<MyStatePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
            Container(
              color: Colors.green,
              padding: const EdgeInsets.all(5.0),
              child: SizedBox(
                width: 100.0,// 設置此值後,子組件設置的寬度無效
                height: 100.0,// 設置此值後,子組件設置的高度無效
                child: Container(
                  color: Colors.red,
                  width: 50.0,
                  height: 150.0,
                ),
              )
            ),
            Divider(height: 15,color: Colors.black,),
            Container(
              color: Colors.green,
              width: 100.0,
              height: 100.0,
              padding: const EdgeInsets.all(5.0),
              // overflowBox包裹的子組件可以溢出容器container
              child: OverflowBox(
                alignment: Alignment.topLeft,// 坐上角對齊
                maxWidth: 150.0, // 最大寬度
                maxHeight: 150.0,// 最大高度
                minWidth: 125.0, // 最小寬度
                minHeight: 125.0,// 最小高度
                // 設置最大最小高度和寬度之後,子組件設置的寬度,高度無效了,小於最小按最小,大於最大按最大
                child: Container(
                  color: Colors.grey,
                  width: 100.0,
                  height: 100.0,
                ),
              ),
            ),
            Divider(height: 50,color: Colors.black,),
            Container(
              color: Colors.green,
              alignment: Alignment.topRight,
              width: 100.0,
              height: 100.0,
              padding: EdgeInsets.all(5.0),
              // 沒弄明白??
              child: SizedOverflowBox(
                size: Size(50.0, 100.0),// 設置width 50 高100
                alignment: Alignment.topLeft,
                child: Container(
                  color: Colors.red, 
                  width: 100.0, 
                  height: 50.0,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

CustomSingleChildLayout

一個自定義的擁有單個子widget的佈局widget。

  • 構造函數
CustomSingleChildLayout({
    Key key,
    @required this.delegate,// 控制自己佈局的委託
    Widget child // 子組件
  }) 

  • 應用示例
class MyStatePageState extends State<MyStatePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("customPainter"),),
      body: Center(
        child: Column(
          children: <Widget>[
            Container(
              color: Colors.blue,
              padding: const EdgeInsets.all(5.0),
              child: CustomSingleChildLayout(
                // 子組件佈局委託類
                delegate: FixedSizeLayoutDelegate(Size(200.0, 200.0)),
                // 子組件
                child: Container(
                  color: Colors.red,
                  width: 100.0,
                  height: 300.0,
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

// 控制子組件佈局的委託類
class FixedSizeLayoutDelegate extends SingleChildLayoutDelegate {
  FixedSizeLayoutDelegate(this.size);

  final Size size;

  @override
  Size getSize(BoxConstraints constraints) => size;

  @override
  BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
    return new BoxConstraints.tight(size);
  }

  @override
  bool shouldRelayout(FixedSizeLayoutDelegate oldDelegate) {
    return size != oldDelegate.size;
  }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章