1. 程式人生 > >(七)Flutter 佈局 建立小部件 自定義view 關於佈局的一些屬性 mainAxis SizeBox Alignment stack AspectRatio ConstrainedBox

(七)Flutter 佈局 建立小部件 自定義view 關於佈局的一些屬性 mainAxis SizeBox Alignment stack AspectRatio ConstrainedBox

主要內容

  • 建立LayoutDemo小部件
  • 建立可配置圖示徽章IconBadege 小部件
  • Row與Column
  • mainAxis:主軸與crossAxis 交叉軸
  • SizeBox 固定尺寸的盒子
  • Alignment 對齊
  • stack 一摞小部件
  • AspectRatio 寬高比
  • ConstrainedBox 帶限制的盒子 

 

關於前兩個就不多做說明 又java基礎的就能看懂 沒有java基礎的我講了你也不懂 所以我就直接上程式碼了

flutter 的Row 和Column

就相當於

android 的orientation 屬性 的horizontal 一行 與 vertical 一列

 

mainAxisAlignment 主軸的對齊方式 

這個主軸 是相對於Cloumn 或者Row來說的

在Cloumn中  那麼主軸就是垂直 

在row 中   那麼主軸就是水平

預設值是start

  mainAxisAlignment: MainAxisAlignment.start,
  mainAxisAlignment: MainAxisAlignment.end,
  mainAxisAlignment: MainAxisAlignment.center,
//把空間分配的小控制元件的周圍
  mainAxisAlignment: MainAxisAlignment.spaceAround,
//把空間分配的小控制元件的之間
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
//把空間平均分配的小控制元件的之間
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,

就是靠前顯示

 

crossAxisAlignment 交叉軸的對齊方式

這個交叉軸 是相對於主軸的交叉出現的 他們有很多數值 

在Cloumn中 因為主軸就是垂直  那麼交叉軸就是水平

在row 中   因為主軸就是水平 那麼交叉軸就是垂直

預設值是

crossAxisAlignment: CrossAxisAlignment.center,

還有其他屬性

//拉伸
 crossAxisAlignment: CrossAxisAlignment.stretch,

start end就不多講了

上案列 

import 'package:flutter/material.dart';
class LayoutDemo extends StatelessWidget{
  @override
    Widget build(BuildContext context) {

      return Container(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            IconBadge(Icons.pool),
            IconBadge(Icons.beach_access,size: 64.0,), 
            IconBadge(Icons.airplanemode_active),
          ],
          
        )
      );
    }
}
class IconBadge extends StatelessWidget{
  final IconData icon;
  final double size;
  IconBadge(this.icon,{this.size=32.0});


  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      child: Icon(icon,size:size,color: Colors.white),
      width: size+60,
      height: size+60,
      color: Color.fromRGBO(3, 54, 255, 1.0),
    );
  }
 
}

sizedBox 這個不僅僅可以設定空間的大小 還可以用來巧妙的設定成間距

 return Container(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,

          children: <Widget>[
          SizedBox(
            width: 200.0,
            height: 300.0,
            child: Container(
              decoration: BoxDecoration(
                color: Color.fromRGBO(3, 54, 255, 1.0),
                borderRadius: BorderRadius.circular(8.0),
              ),
            child: Icon(Icons.ac_unit,color: Colors.white,size: 32.0,),
            ),
          ),
          SizedBox(
            height:20.0
          ),
           SizedBox(
            width: 100.0,
            height: 100.0,
            child: Container(
              decoration: BoxDecoration(
                color: Color.fromRGBO(3, 54, 255, 1.0),
                borderRadius: BorderRadius.circular(8.0),
              ),
            child: Icon(Icons.brightness_2,color: Colors.white,size: 32.0,),
            ),
          )
          ],
          
        )
      );

alignment 對齊

語法

alignment: Alignment(1.0, 1.0),

取值範圍 -1~1

具體應用 就是相當於Android 相對佈局中的AliginParent屬性

對於控制元件的 android:layout_alignParent 屬性,只有在該佈局的父佈局也是RelativeLayout是才有用,此屬性的含義為將控制元件邊緣與父控制元件的邊緣對齊

android:layout_alignParentLeft="true"  --將控制元件的左邊緣和父控制元件的左邊緣對齊
android:layout_alignParentTop="true"  --將控制元件的上邊緣和父控制元件的上邊緣對齊
android:layout_alignParentRight="true"  --將控制元件的右邊緣和父控制元件的右邊緣對齊
android:layout_alignParentBottom="true" --將控制元件的底邊緣和父控制元件的底邊緣對齊

android:layout_centerInParent="true"  --將控制元件置於父控制元件的中心位置
android:layout_centerHorizontal="true"  --將控制元件置於水平方向的中心位置
android:layout_centerVertical="true"  --將控制元件置於垂直方向的中心位置

預設的位置就是0,0

實際應用如下 可以理解為child再SizeBox中的位置 左上是-1,-1 右下是1,1

這個樣子的設計我還覺得挺新穎的

 SizedBox(
            width: 200.0,
            height: 300.0,
            child: Container(
              alignment: Alignment(0.0, 0.0),
              decoration: BoxDecoration(
                color: Color.fromRGBO(3, 54, 255, 1.0),
                borderRadius: BorderRadius.circular(8.0),
              ),
            child: Icon(Icons.ac_unit,color: Colors.white,size: 32.0,),
            ),
          ),

當然 Flutter作為後起之秀不是沒有原因的,真的是細節做的很好 他為了少讓你自己算0,-0.5  還是 -0.5 0,量身定製了api

  alignment: Alignment.topCenter,

我就不一一列舉了 自己嘗試把

Stack 相當於Android的相對佈局

把一堆小空間疊加起來 直接上程式碼吧

import 'package:flutter/material.dart';
class LayoutDemo extends StatelessWidget{
  @override
    Widget build(BuildContext context) {

      return Container(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,

          children: <Widget>[
          Stack(children: <Widget>[
            SizedBox(
            width: 200.0,
            height: 300.0,
            child: Container(
              alignment: Alignment.topCenter,
              decoration: BoxDecoration(
                color: Color.fromRGBO(3, 54, 255, 1.0),
                borderRadius: BorderRadius.circular(8.0),
              ),
            child: Icon(Icons.ac_unit,color: Colors.white,size: 32.0,),
            ),
          ),
          SizedBox(
            height:20.0
          ),
           SizedBox(
            width: 100.0,
            height: 100.0,
            child: Container(
              decoration: BoxDecoration(
                color: Color.fromRGBO(3, 54, 255, 1.0),
                borderRadius: BorderRadius.circular(8.0),
              ),
            child: Icon(Icons.brightness_2,color: Colors.white,size: 32.0,),
            ),
          )
          ],)
          ],
          
        )
      );
    }
}
class IconBadge extends StatelessWidget{
  final IconData icon;
  final double size;
  IconBadge(this.icon,{this.size=32.0});


  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      child: Icon(icon,size:size,color: Colors.white),
      width: size+60,
      height: size+60,
      color: Color.fromRGBO(3, 54, 255, 1.0),
    );
  }
 
}

Positioned 控制控制元件的位置

   Positioned(
            right: 20.0,
            top: 120.0,
              child: Icon(Icons.ac_unit,color: Colors.white,size: 16.0,),)
          ],)

so 畫一個星空圖 有月亮還有星辰 

import 'package:flutter/material.dart';

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Stack(
          alignment: Alignment.topLeft,
          children: <Widget>[
            SizedBox(
              width: 200.0,
              height: 300.0,
              child: Container(
                alignment: Alignment.topCenter,
                decoration: BoxDecoration(
                  color: Color.fromRGBO(3, 54, 255, 1.0),
                  borderRadius: BorderRadius.circular(8.0),
                ),
              ),
            ),
            SizedBox(height: 20.0),
            SizedBox(
              
              width: 100.0,
              height: 100.0,
              child: Container(
                decoration: BoxDecoration(
                    color: Color.fromRGBO(3, 54, 255, 1.0),
                    shape: BoxShape.circle,
                    gradient: RadialGradient(colors: [
                      Color.fromRGBO(7, 102, 255, 1.0),
                      Color.fromRGBO(3, 54, 255, 1.0),
                    ])),
                child: Icon(
                  Icons.brightness_2,
                  color: Colors.white,
                  size: 32.0,
                ),
              ),
            ),
            Positioned(
                right: 20.0,
                top: 120.0,
                child: Icon(Icons.ac_unit, color: Colors.white, size: 20.0)
                ),
            Positioned(
                right: 70.0,
                top: 180.0,
                child: Icon(Icons.ac_unit, color: Colors.white, size: 16.0)
                ),
            Positioned(
                right: 30.0,
                top: 230.0,
                child: Icon(Icons.ac_unit, color: Colors.white, size: 18.0)
                ),
            Positioned(
                right: 90.0,
                top: 20.0,
                child: Icon(Icons.ac_unit, color: Colors.white, size: 20.0)
                ),
            Positioned(
                right: 4.0,
                top: -4.0,
                child: Icon(Icons.ac_unit, color: Colors.white, size: 16.0)
                ),
          ],
        )
      ],
    ));
  }
}

class IconBadge extends StatelessWidget {
  final IconData icon;
  final double size;
  IconBadge(this.icon, {this.size = 32.0});

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      child: Icon(icon, size: size, color: Colors.white),
      width: size + 60,
      height: size + 60,
      color: Color.fromRGBO(3, 54, 255, 1.0),
    );
  }
}

AspectRatio 來製造寬高比的容器

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        AspectRatio(
          aspectRatio:1.0/1.0 ,
          child: Container(
            color: Color.fromRGBO(3, 54, 255, 1.0),
          ),
        ),
      ],
     

    )
    );
  }
}

其中 aspectRatio:1.0/1.0 ,

就是說1比上1  也可以改成16/9  3/2等值進行測試

ConstrainedBox 帶限制的盒子

可以設定最小高度和最大高度等引數

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[ConstrainedBox(
        constraints: BoxConstraints(
          minHeight: 200.0,
          maxWidth: 200.0
        ),
        child: Container(
          color: Color.fromRGBO(3, 54, 255, 1.0),
        ),
      )],
    ));
  }
}