Container

作者: CoderGuogt | 来源:发表于2019-12-21 16:10 被阅读0次

Container

1.简介

ContainerFlutter中太常见了。官方给出的简介,是一个结合了绘制painting、定位positioning以及尺寸sizing widgetwidget

可以得出几个信息,它是一个组合的widget,内部有绘制widget、定位widget、尺寸widget。后续看到的不少widget,都是通过一些更基础的widget组合而成的。

1.2 组成

Container的组成如下:

  • 最里层的是child元素
  • child元素首先会被padding包着
  • 然后添加额外的constraints限制
  • 最后添加margin

Container的绘制的过程如下:

  • 首先会绘制transform效果
  • 接着绘制decoration
  • 然后绘制child
  • 最后绘制foregroundDecoration

Container自身尺寸的调节分两种情况:

  • Container在没有子节点children的时候,会试图去变得足够大。除非constraintsunbounded限制,在这种情况下,Container会试图去变得足够小。
  • 带子节点的Container,会根据子节点尺寸调节自身尺寸,但是Container构造器中如果包含了widthheight以及constraints,则会按照构造器中的参数来进行尺寸的调节。

1.2 布局行为

由于Container组合了一系列的widget,这些widget都有自己的布局行为,因此Container的布局行为有时候是比较复杂的。

一般情况下,Container会遵循如下顺序去尝试布局:

  • 对齐alignment
  • 调节自身尺寸适合子节点
  • 采用widthheight以及constraints布局
  • 扩展自身去适应父节点
  • 调节自身到足够小

进一步说:

  • 如果没有子节点、没有设置widthheight以及constraints,并且父节点没有设置unbounded的限制,Container会将自身调整到足够小。
  • 如果没有子节点、对齐方式alignment,但是提供了widthheight或者constraints,那么Container会根据自身以及父节点的限制,将自身调节到足够小。
  • 如果没有子节点childwidthheightconstraints以及alignment,但是父节点提供了bounded限制,那么Container会按照父节点的限制,将自身调整到足够大。
  • 如果有alignment,父节点提供了unbounded限制,那么Container将会调节自身尺寸来包住child
  • 如果有alignment,并且父节点提供了bounded限制,那么Container会将自身调整的足够大(在父节点的范围内),然后将child根据alignment调整位置;
  • 含有child,但是没有widthheightconstraints以及alignmentContainer会将父节点的constraints传递给child,并且根据child调整自身。

另外,margin以及padding属性也会影响到布局。

1.3 属性

keyContainer唯一标识符,用于查找更新。

alignment:控制child的对齐方式,如果container或者container父节点尺寸大于child的尺寸,这个属性设置会起作用,有很多种对齐方式。

paddingdecoration内部的空白区域,如果有child的话,child位于padding内部。paddingmargin的不同之处在于,padding是包含在content内,而margin则是外部边界,设置点击事件的话,padding区域会响应,而margin区域不会响应。

color:用来设置container背景色,如果foregroundDecoration设置的话,可能会遮盖color效果。

decoration:绘制在child后面的装饰,设置了decoration的话,就不能设置color属性,否则会报错,此时应该在decoration中进行颜色的设置。

foregroundDecoration:绘制在child前面的装饰。

widthcontainer的宽度,设置为double.infinity可以强制在宽度上撑满,不设置,则根据child和父节点两者一起布局。

heightcontainer的高度,设置为double.infinity可以强制在高度上撑满。

constraints:添加到child上额外的约束条件。

margin:围绕在decorationchild之外的空白区域,不属于内容区域。

transform:设置container的变换矩阵,类型为Matrix4

childcontainer中的内容widget

2.使用

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Container的使用',
      home: Scaffold(
          appBar: AppBar(
            title: Text('Container的使用'),
          ),
          body: Center(
            child: SingleChildScrollView(
              child: Column(
                children: <Widget>[
                  _x48Box(context),
                  otherFeatures(context),
                  borderUse(context),
                ],
              ),
            ),
          )),
    );
  }

  /// 创建一个 48x48 的矩形盒子
  Widget _x48Box(BuildContext context) {
    return Container(
      width: 48,
      height: 48,
      color: Colors.orange,
      margin: EdgeInsets.all(10.0),
    );
  }

  /// 使用 Container 其他属性
  Widget otherFeatures(BuildContext context) {
    return Container(
      constraints: BoxConstraints.expand(
        height: Theme.of(context).textTheme.display1.fontSize * 1.1 + 200,
      ),
      padding: EdgeInsets.all(10),
      color: Colors.blueGrey,
      alignment: Alignment.center,
      child: Text('Hello world',
          style: Theme.of(context)
              .textTheme
              .display1
              .copyWith(color: Colors.white)),
    );
  }

  Widget borderUse(BuildContext context) {
    return Container(
      decoration: const BoxDecoration(
        border: Border(
          top: BorderSide(width: 1.0, color: Color(0xFFFF00FF00)),
          left: BorderSide(width: 1.0, color: Color(0xFFFF0000FF)),
          right: BorderSide(width: 1.0, color: Color(0xFFFF000000)),
          bottom: BorderSide(width: 1.0, color: Color(0xFFFF000000)),
        ),
      ),
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0),
        decoration: const BoxDecoration(
          border: Border(
            top: BorderSide(width: 1.0, color: Color(0xFFFF0000)),
            left: BorderSide(width: 1.0, color: Color(0xFFFFFF0000)),
            right: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)),
            bottom: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)),
          ),
          color: Color(0xFFFFBFBFBF),
        ),
        child: const Text('OK',
            textAlign: TextAlign.center,
            style: TextStyle(color: Color(0xFF000000))),
      ),
    );
  }
}

借鉴于大佬
Container 官方文档

相关文章

网友评论

      本文标题:Container

      本文链接:https://www.haomeiwen.com/subject/vbygnctx.html