【Flutter】(Column、Padding、Stack)

426 阅读3分钟

Column 垂直布局

  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>[],
  }) : super(
    children: children,
    key: key,
    direction: Axis.vertical,
    mainAxisAlignment: mainAxisAlignment,
    mainAxisSize: mainAxisSize,
    crossAxisAlignment: crossAxisAlignment,
    textDirection: textDirection,
    verticalDirection: verticalDirection,
    textBaseline: textBaseline,
  );

children:子控件集合

mainAxisAlignment:主轴方向的排布方式,由于是竖向布局,其主轴是竖向的垂直线

1、center:主轴中心
2start:主轴起点
3end:主轴末尾
4、spaceAround:主轴中间空白区域均分,首尾空白区域为1/2
5、spaceBetween:主轴中间空白区域均分,首尾没有空白区域
6、spaceEvenly:主轴中间空白区域均分,首尾平分空白区域

mainAxisSize:主轴方向占有空间的值

1、max:占用最大空间
2、min:占用最小空间

crossAxisAlignment:侧轴方向的排布方式,由于是竖向布局,其侧轴是横向的水平线

1、baseline:侧轴与baseline对齐
2、center:侧轴居中显示
3、end:侧轴末尾显示
4、start:侧轴起点显示
5、stretch:侧轴填满显示

textDirection:文字的排布方式

1、TextDirection.ltr:从左到右
2、TextDirection.rtl:从右到左

verticalDirection:子控件的排布方式

1、down:从左上角到右下角进行布局
2、up:从右下角到左上角进行布局

textBaseline:文字的基准线

详情可参考:Flutter: 图解 Row 与 Column

Padding

  const Padding({
    Key key,
    @required this.padding,
    Widget child,
  }) : assert(padding != null),
       super(key: key, child: child);

child:子控件

当child为空的时候,会产生一个宽为left+right,高为top+bottom的区域;
当child不为空的时候,Padding会将布局约束传递给child,根据设置的padding属性,缩小child的布局尺寸。然	Padding将自己调整到child设置了padding属性的尺寸,在child周围创建空白区域。

padding:EdgeInsets 设置填充的值

Stack

  Stack({
    Key key,
    this.alignment = AlignmentDirectional.topStart,
    this.textDirection,
    this.fit = StackFit.loose,
    this.overflow = Overflow.clip,
    this.clipBehavior = Clip.hardEdge,
    List<Widget> children = const <Widget>[],
  }) : assert(clipBehavior != null),
       super(key: key, children: children);

alignment

此参数决定如何去对齐没有定位(没有使用Positioned)或部分定位的子组件。所谓部分定位,
在这里特指只在某一个轴上定位:leftright为横轴,topbottom为纵轴,只要包含某个轴上
的一个定位属性就算在该轴上有定位。

textDirection

Row、Wrap的textDirection功能一样,都用于确定alignment对齐的参考系,即:textDirection的
值为TextDirection.ltr,那么alignment的start则代表左,end就是代表右,即从左往右的顺序;如果
textDirection的值为TextDirection.rtl,那么alignment的start则代表右,end就是代表左,即从
右往左的顺序。

fit

此参数用于确定没有定位的子组件如何去适应Stack的大小。StackFit.loose代表使用子组件的大小,
StackFit.expand表示扩伸到Stack大小。

overflow

此属性决定如何显示超出Stack显示空间的子组件;overflow的值为Overflow.clip时,超出部分会被
裁剪,overflow的值为Overflow.visible时则不会。

代码

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(0, 100, 0, 0),
          child: Container(
            color: Colors.blue,
            width: MediaQuery.of(context).size.width,
            height: 100,
            child: Stack(
              children: <Widget>[
                Positioned(
                    child: ClipPath(
                      clipper:StartTimeClipper() ,
                      child: Container(
                          color: Colors.red,
                          child: GestureDetector(
                            onTap: (){
                              print("点击红色");
                            },
                          ),
                      ),
                    )
                ),
                Positioned(
                    child: ClipPath(
                      clipper: EndTimeClipper(),
                      child: Container(
                        color: Colors.yellow,
                        child: GestureDetector(
                          onTap:() {
                            print("点击黄色");
                          },
                        ),
                      ),
                    ),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}

class StartTimeClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final path = Path();
    path.lineTo(size.width * 1/2 , 0.0);
    path.lineTo(size.width * 1/4, size.height);
    path.lineTo(0.0, size.height);
    path.close();
    return path;
  }
  @override
  bool shouldReclip(StartTimeClipper oldClipper) => false;
}

class EndTimeClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final path = Path();
    path.moveTo(size.width * 1/2 , 0.0);
    path.lineTo(size.width , 0.0);
    path.lineTo(size.width, size.height);
    path.lineTo(size.width * 1/4, size.height);
    path.close();
    return path;
  }
  @override
  bool shouldReclip(EndTimeClipper oldClipper) => false;
}