• Flutter and Dart series articles
  • GitHub address of the project
  • Container classesWidgetAnd the layout of the classWidgetThey all act on their childrenWidget, the difference is:
    • Layout of the classWidgetUsually you need to receive onewidgetArray (children), they directly or indirectly inherit from (or contain)MultiChildRenderObjectWidget
    • The container classWidgetGenerally, you only need to accept one coinWidget(child), they directly or indirectly inherit from (or contain)SingleChildRenderObjectWidget
    • Layout of the classWidgetIt pairs its children in a certain arrangementWidgetTo arrange
    • The container classWidgetGenerally just packaging the childWidget, add some embellishment (fill or background color, etc.), transform (rotate or crop, etc.), or restrict (size, etc.).
  • FlutterThe authorities are not rightWidgetOfficial classification, our classification is mainly for the convenience of discussion and comparisonWidgetFunction of differentiated memory
  • Related container classesWidgetIt is mainly divided into the following types
    • Fill class containerPadding
    • Layout restriction class containersConstrainedBox,SizeBox
    • Decorative containerDecoratedBox
    • Transformation class containerTransform
    • Combination of the containerContainer
    • Navigation containerScaffold,TabBar,AppBarEtc.

Padding

Padding allows you to set an inner margin for its child elements

class Padding extends SingleChildRenderObjectWidget {
    const Padding({
        Key key,
        / / padding
        @required this.padding,
        Widget child,
    })
    
    final EdgeInsetsGeometry padding;
}
Copy the code

EdgeInsetsGeometry is an abstract class that generally uses EdgeInsets. EdgeInsetsGeometry is a subclass of EdgeInsetsGeometry, and some methods are defined below

class EdgeInsets extends EdgeInsetsGeometry {
    // Set margins according to upper, lower, left, and right
    const EdgeInsets.fromLTRB(this.left, this.top, this.right, this.bottom);

    // set four peripherals
    const EdgeInsets.all(double value)
    
    // Set only some of the margins
    const EdgeInsets.only({
        // The following are the default values
        this.left = 0.0.this.top = 0.0.this.right = 0.0.this.bottom = 0.0
    });
    
    // According to the horizontal and vertical direction, the same spacing up and down, the same spacing left and right
    const EdgeInsets.symmetric({ double vertical = 0.0.double horizontal = 0.0 })
                             
    // Static variables, up, down, left, and right, are 0
    static const EdgeInsets zero = EdgeInsets.only();
}
Copy the code

The sample

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(20), child: Icon(Icons.phone, color: Colors.cyan,), ); }}Copy the code

ConstrainedBox

  • ConstrainedBoxandSizedBoxIs throughRenderConstrainedBoxTo render the
  • SizedBoxjustConstrainedBoxA custom
  • ConstrainedBoxMainly used in pairswidgetAdd additional constraints
class ConstrainedBox extends SingleChildRenderObjectWidget {
  
  ConstrainedBox({
    Key key,
    @required this.constraints,
    Widget child
  })

  /// Add constraints to the child widgets
  final BoxConstraints constraints;
Copy the code

BoxConstraints

BoxConstraints sets the constraints on the Widget by internally setting four properties: maximum/small width and maximum size height. The associated constructors and instance functions are shown below

class BoxConstraints extends Constraints {
  /// constructor
  const BoxConstraints({
    // Minimum width
    this.minWidth = 0.0.// Maximum width
    this.maxWidth = double.infinity,
    // Minimum height
    this.minHeight = 0.0.// Maximum height
    this.maxHeight = double.infinity
  });

  // set the constraint based on the specified Size
  BoxConstraints.tight(Size size)
    : minWidth = size.width,
      maxWidth = size.width,
      minHeight = size.height,
      maxHeight = size.height;

  // According to the specified width and height Settings, the parameter can be null
  const BoxConstraints.tightFor({
    double width,
    doubleheight }): minWidth = width ! =null ? width : 0.0, maxWidth = width ! =null ? width : double.infinity, minHeight = height ! =null ? height : 0.0, maxHeight = height ! =null ? height : double.infinity;

  // The default width and height are the maximum, and the parameter can be null
  const BoxConstraints.tightForFinite({
    double width = double.infinity,
    double height = double.infinity }): minWidth = width ! =double.infinity ? width : 0.0, maxWidth = width ! =double.infinity ? width : double.infinity, minHeight = height ! =double.infinity ? height : 0.0, maxHeight = height ! =double.infinity ? height : double.infinity;

  // Set the maximum value and minimum value to 0 according to the Size parameter
  BoxConstraints.loose(Size size)
    : minWidth = 0.0,
      maxWidth = size.width,
      minHeight = 0.0,
      maxHeight = size.height;
      
  // Depending on the width and height, if the parameter is empty, the default value is the maximum value
  const BoxConstraints.expand({
    double width,
    doubleheight }): minWidth = width ! =null ? width : double.infinity, maxWidth = width ! =null ? width : double.infinity, minHeight = height ! =null ? height : double.infinity, maxHeight = height ! =null ? height : double.infinity;
}
Copy the code

Using the instance

class ConstrainedBoxView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return ConstrainedBox(
      constraints: BoxConstraints(
        minWidth: double.infinity,  // Set the width to the maximum
        minHeight: 50.// The minimum height is set to 50
      ),
      child: Container(
        height: 10.// Set the height to 10child: DecoratedBox(decoration: BoxDecoration(color: Colors.orange)), ), ); }}Copy the code

  • As you can see, although willContainerThe height is set to 10 pixels, but it ends up being 50 pixels, which is exactly what it isConstrainedBoxThe minimum height limit is in effect
  • If you haveContainerSet the height of the red area to 80 pixels, because in this example,ConstrainedBoxOnly the minimum height is restricted, not the maximum height

SizedBox

The SizedBox is used to specify a fixed width and height for the child widgets

// Several constructors for SizedBox
class SizedBox extends SingleChildRenderObjectWidget {
  /// Set a fixed height
  const SizedBox({ Key key, this.width, this.height, Widget child })
    : super(key: key, child: child);

  // create a box with the maximum width and height
  const SizedBox.expand({ Key key, Widget child })
    : width = double.infinity,
      height = double.infinity,
      super(key: key, child: child);

  /// create a box with minimum width and height (both 0)
  const SizedBox.shrink({ Key key, Widget child })
    : width = 0.0,
      height = 0.0.super(key: key, child: child);

  // create a box with the specified size
  SizedBox.fromSize({ Key key, Widget child, Size size })
    : width = size?.width,
      height = size?.height,
      super(key: key, child: child);
}
Copy the code

Here we create a Widget that specifies the width and height

class SizedBoxView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return SizedBox(
      width: 80,
      height: 80, child: Container( child: DecoratedBox(decoration: BoxDecoration(color: Colors.orange)), ), ); }}// In fact SizedBox and just ConstrainedBox are a custom, the above code is equivalent to
ConstrainedBox(
  constraints: BoxConstraints.tightFor(width: 80.0,height: 80.0),
  child: Container(
    child: DecoratedBox(decoration: BoxDecoration(color: Colors.orange)),
  ),
)
Copy the code

In fact, ConstrainedBox and SizedBox are rendered with RenderConstrainedBox, We can see that ConstrainedBox and the SizedBox createRenderObject() method both return a RenderConstrainedBox object

// SizedBox
class SizedBox extends SingleChildRenderObjectWidget {
 RenderConstrainedBox createRenderObject(BuildContext context) {
    return RenderConstrainedBox(
      additionalConstraints: _additionalConstraints,
    );
  }

  BoxConstraints get _additionalConstraints {
    return BoxConstraints.tightFor(width: width, height: height);
  }
}

// ConstrainedBox
class ConstrainedBox extends SingleChildRenderObjectWidget {
  RenderConstrainedBox createRenderObject(BuildContext context) {
    return RenderConstrainedBox(additionalConstraints: constraints);
  }

  final BoxConstraints constraints;
}
Copy the code

Multiple constraint problem

  • If one of themwidgetThere is more than one parentConstrainedBoxlimit
  • forminWidthandminHeightFor example, take the parent with the largest corresponding value. Only in this way can we ensure that the parent restriction does not conflict with the child restriction
  • formaxWidthandmaxHeightIt doesn’t work, it ends up being 0 in width and height

UnconstrainedBox

const UnconstrainedBox({
    Key key,
    Widget child,
    // TextDirection, which represents the layout order of the horizontal child widgets
    this.textDirection,
    // How the child widgets are aligned on the main axis
    this.alignment = Alignment.center,
    // Set the constraint's Axis, horizontal or vertical, Axis. Horizontal
    this.constrainedAxis,
})
Copy the code
  • UnconstrainedBoxWon’t pairWidgetProduces any restrictions that allow its childrenWidgetDraw it to its own size
  • In general, we rarely use this directlywidgetBut it might be helpful to “remove” multiple restrictions
ConstrainedBox(
  constraints: BoxConstraints(
    minWidth: 60,
    minHeight: 100,
  ),
  child: UnconstrainedBox(  // "remove" the parent limit
    textDirection: TextDirection.ltr,
    alignment: Alignment.center,
    constrainedAxis: Axis.horizontal,
    child: ConstrainedBox(
      constraints: BoxConstraints(
        minWidth: 90,
        minHeight: 20,
      ),
      child: DecoratedBox(decoration: BoxDecoration(color: Colors.red)),
    ),
  )
);
Copy the code
  • In the code above, if there is no middleUnconstrainedBoxAccording to the multiple restrictions rule described above, a red box of 90×100 will be displayed
  • But because theUnconstrainedBox“Remove” the fatherConstrainedBoxLimit, then will eventually according to the childConstrainedBoxLimit to draw the red box, i.e. 90×20:

  • But be careful,UnconstrainedBoxThe “removal” of the parent constraint is not a true removal; in the example above, although the red area is 90×20, there is still 80 blank space above it.
  • In other words, father-limitedminHeight(100.0) is still valid, but it does not affect the size of the final child element, but it still occupies the corresponding space and can be considered the parentConstrainedBoxTheta operates on phiConstrainedBoxOn, and the red box only accepts the sonConstrainedBoxLimit, this point please readers must pay attention to
  • And there’s no way to get rid of the father, rightBoxConstraintsThe limits of
  • In defining a genericwidgetWhen, if pairwidgetBe careful when specifying restrictions, because once you specify restrictions, the childwidgetIf you want to do the relevant custom size will be very difficult, because the childwidgetDo not change the parentwidgetCan’t completely remove its restriction condition

DecoratedBox

The DecoratedBox can draw a Decoration (such as background, border, gradient, etc.) before (or after) its child widget

const DecoratedBox({
    Key key,
    @required this.decoration,
    this.position = DecorationPosition.background,
    Widget child
})
Copy the code
  • decoration: represents the decoration to be painted, of typeDecorationIs an abstract class that defines an interfacecreateBoxPainter()The primary responsibility of a subclass is to implement it to create a decorator, so we’ll use it laterBoxDecorationTo implement the property
  • positionThis property determines where to drawDecorationIt receivesDecorationPositionThe enumeration class has two values:
    • background: in the childwidgetDraw after, that is, background decoration (default)
    • foreground: in the childwidgetPainted above, that is, the foreground

BoxDecoration

BoxDecoration is a subclass of Decoration, which is usually used to implement properties similar to Decoration

const BoxDecoration({
    // Background color
    this.color,
    // Background image, DecorationImage
    this.image,
    / / frame
    this.border,
    / / the rounded
    this.borderRadius,
    / / the shadow
    this.boxShadow,
    / / gradients
    this.gradient,
    // BlendMode is the blend rendering mode of the background color and the background image
    this.backgroundBlendMode,
    / / shape
    this.shape = BoxShape.rectangle,
})
Copy the code

image

Set the background image DecorationImage

const DecorationImage({
    / / ImageProvider type
    @required this.image,
    this.colorFilter,
    this.fit,
    this.alignment = Alignment.center,
    this.centerSlice,
    this.repeat = ImageRepeat.noRepeat,
    this.matchTextDirection = false,})Copy the code

image

  • The way the image is set, yesImageProviderThe type of
  • ImageProviderIs an abstract class that needs to be implemented using subclasses
    • NetworkImage
    • FileImage
    • MemoryImage

colorFilter

  • The color filter applied to the image before drawing it, the property value isColorFilterclass
  • ColorFilterThe constructor has two properties that set the color image and the picture image, which will also be used later to explain the enumeration values
// Set the color image and the image image respectively
const ColorFilter.mode(Color color, BlendMode blendMode)
Copy the code

BlendMode has the following enumeration values, with SRC indicating that the image is not displayed, and DST indicating that the color image is not displayed

blendMode Enumeration value meaning
clear Color images and picture images are not displayed
src Show color images do not show picture images
dst Display picture images do not display color images
srcOver The color image is above the picture image
dstOver The color image is below the picture image
srcIn Displays a picture image, but only what overlaps with the color image.
dstIn Display the color image, but only the overlap with the image image (the intersection of the two)
srcOut Display the picture image, but only the parts that do not coincide with the color image (the difference between the two)
dstOut Display color image, but only display and image image does not coincide with the part (the difference between the two), generally empty
srcATop Synthesize the picture image onto the color image, only the intersection part
dstATop Composes the color image onto the picture image, only the intersection part
xor Image image and color image composition results
plus Image and color composition, but affected by transparency
modulate Multiply the color components of the picture image and the color image. This can only produce the same or darker color (multiply by white, 1.0, the result remains the same; Multiplied by black, 0.0, the result is black
screen Multiply the reciprocal of the color components of the picture image and the color image and reverse the result
overlay After adjusting the components of the picture image and color image to favor the target, multiply them
darken Compose a picture image and a color image by selecting the lowest value from each color channel
lighten Compose picture images and color images by selecting the highest value from each color channel

There are several enumerated values, but I really don’t know how to explain the above explanation seems to is not very clear, vaguely, suggest you see the effect self-test PIC, or look at the official documents, also have renderings, actually a lot of enumeration values or use less than, if there is a good explanation, Suggestions are welcome at……… Embarrassment of capitals

border

To set the style of the border,BoxBorder is an abstract class with three implementations of the following two classes

// Two implementations of Border
class Border extends BoxBorder {
  const Border({
    this.top = BorderSide.none,
    this.right = BorderSide.none,
    this.bottom = BorderSide.none,
    this.left = BorderSide.none,
  })
  
  factory Border.all({
    Color color = const Color(0xFF000000),
    double width = 1.0,
    BorderStyle style = BorderStyle.solid,
  })
}

// Below is the BorderSide constructor, which was introduced in the previous text but is not covered here
class BorderSide {
  const BorderSide({
    this.color = const Color(0xFF000000),
    this.width = 1.0.this.style = BorderStyle.solid,
  })
}

// BorderDirectional's constructor
class BorderDirectional extends BoxBorder {
  const BorderDirectional({
    this.top = BorderSide.none,
    this.start = BorderSide.none,
    this.end = BorderSide.none,
    this.bottom = BorderSide.none,
  })
}
Copy the code

boxShadow

Set the box’s shadows, which match the box’s shape, and accept a list of stored BoxShadows. Let’s look at the BoxShadow constructor

const BoxShadow({
    / / color
    Color color = const Color(0xFF000000),
    // The offset of the shadow relative to the box
    Offset offset = Offset.zero,
    // The blur degree of the shadow, the larger the value, the more blurred the shadow
    double blurRadius = 0.0.// The shadow increases the pixel value in the opposite direction
    this.spreadRadius = 0.0
})

// Add shadows to all four edges
[
    BoxShadow(color: Colors.grey, offset: Offset(- 5.- 5), blurRadius: 10, spreadRadius: 0),
    BoxShadow(color: Colors.red, offset: Offset(5.5), blurRadius: 10, spreadRadius: 0)],Copy the code

gradient

Set the background color to Gradient, which is an abstract class, and there are three subclasses below

  • LinearGradient
  • RadialGradient
  • SweepGradient
// Linear gradient
const LinearGradient({
    / / starting point
    this.begin = Alignment.centerLeft,
    / / the end
    this.end = Alignment.centerRight,
    // Array of color values
    @required List<Color> colors,
    // List of values, containing values from 0.0 to 1.0
    List<double> stops,
    // Gradient tiling mode, specify tiling mode in areas other than the start and end
    this.tileMode = TileMode.clamp,
})

// Circle gradient,
const RadialGradient({
    // Center of gradient)
    this.center = Alignment.center,
    // The radius of the gradient is a floating-point number multiplied by the width of the box
    this.radius = 0.5.@required List<Color> colors,
    List<double> stops,
    this.tileMode = TileMode.clamp,
    this.focal,
    this.focalRadius = 0.0
})

const SweepGradient({
    // The center point of the position
    this.center = Alignment.center,
    // Angle of the starting point
    this.startAngle = 0.0.// The Angle of the end
    this.endAngle = math.pi * 2.@required List<Color> colors,
    List<double> stops,
    this.tileMode = TileMode.clamp,
})
Copy the code

The three gradient effects are shown below

In LinearGradient, the effects of each enumerated value of TileMode are as follows

shape

Sets the shape of the background. BoxShape is an enumerated value for the background color, background image, and gradient

enum BoxShape {
  // Keep the same
  rectangle,

  // Clipping to a circle conflicts with the borderRadius property
  circle,
}
Copy the code

Transform

  • TransformCan be in the childWidgetWhen you draw it, you apply a matrix transformation to itchildDo translation, rotation, scaling and other operations
  • Matrix4Is a 4D matrix through which various matrix operations can be implemented

Transform

Let’s take a look at some of the constructors for Transform

class Transform extends SingleChildRenderObjectWidget {
  // Create a matrix transform Widget
  const Transform({
    Key key,
    // The matrix performs transformations that accept a Matrix4 object
    @required this.transform,
    
    // The rotation point, offset from the top left vertex. The default rotation point is the top left vertex,
    // Accept an Offset object
    this.origin,
    // To its way
    this.alignment,
    // The click area should also be changed accordingly
    this.transformHitTests = true,
    Widget child,
  })
  
  // Create a rotation transformation matrix
  Transform.rotate({
    Key key,
    // Set the rotation Angle
    @required double angle,
    this.origin,
    this.alignment = Alignment.center,
    this.transformHitTests = true,
    Widget child,
  })
  
  // Create a translation matrix
  Transform.translate({
    Key key,
    @required Offset offset,
    this.transformHitTests = true,
    Widget child,
  })
  
  // Create a scaling matrix
  Transform.scale({
    Key key,
    // Set the scale from 0 to 1
    @required double scale,
    this.origin,
    this.alignment = Alignment.center,
    this.transformHitTests = true,
    Widget child,
  })
}
Copy the code

Below are concrete examples of each form of transformation

rotating

Transform.rotate Can rotate child widgets as shown in the following code

Container(
  color: Colors.black,
  child: Transform.rotate(
    ☞ Angle of rotation, math. PI refers to 180 degrees
    angle: -math.pi / 4,
    child: Container(
      padding: const EdgeInsets.all(8.0),
      color: const Color(0xFFE8581C),
      child: const Text('https://titanjun.top'),)))Copy the code

translation

Transform.translate receives an offset argument that can be translated to the child widget by a specified distance along the X and y axes when drawing

Container(
  color: Colors.black,
  child: Transform.translate(
    // The default origin is the upper left corner, shifted 5 pixels to the right, shifted 15 pixels down
    offset: const Offset(5.0.15.0),
    child: Container(
      padding: const EdgeInsets.all(8.0),
      color: const Color(0xFF7F7F7F),
      child: const Text('Quarter'),)))Copy the code

The zoom

Transform.scale can be used to shrink or enlarge child widgets

Container(
  color: Colors.black,
  child: Transform.scale(
    origin: Offset(5.5),
    // Shrink by 0.5 times
    scale: 0.5,
    child: Container(
      padding: const EdgeInsets.all(8.0),
      color: const Color(0xFFE8581C),
      child: const Text('Bad Ideas'),)))Copy the code

Pay attention to the point

  • TransformThe transformation is applied to the drawing phase, not to the layout (layout) phase
  • So no matter what changes are applied to the child widget, the amount of space it takes up and its position on the screen remain constant, because these are determined during the layout phase
Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    DecoratedBox(
      decoration:BoxDecoration(color: Colors.red),
      child: Transform.scale(scale: 1.5,
          child: Text("Hello world")
      )
    ),
    Text("Hello", style: TextStyle(color: Colors.green, fontSize: 18.0),) ",Copy the code

  • Because of the first oneTextAfter applying transformation (magnification), it will be enlarged when drawing, but it still takes up the space of the red part, so the secondtextIt’s going to be right next to the red, and eventually there’s going to be some overlap.
  • Since matrix changes only affect the drawing stage, in some scenarios, when UI needs to be changed, visual UI changes can be directly achieved through matrix changes without re-triggering the build process, which will save moneylayoutOverhead, so the performance will be better
  • As introduced earlierFlow widgetInternally, it’s updating the UI with matrix transformations, and other than that,FlutterThe animationwidgetIs also widely used inTransformTo improve performance

RotatedBox

  • RotatedBoxandTransform.rotateFunctionally similar, they can both be pairedwidgetPerform the rotation transform, but with one difference:RotatedBoxThe transformation of phi is zerolayoutThe phase will affect the subwidgetThe location and size of
  • We will introduce it aboveTransform.rotateChange the example of
Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    DecoratedBox(
      decoration: BoxDecoration(color: Colors.red),
      Transform. Rotate to RotatedBox
      child: RotatedBox(
        / / int type
        quarterTurns: 1.// Rotate 90 degrees (1/4 turn)
        child: Text("Hello world"),
      ),
    ),
    Text("Hello", style: TextStyle(color: Colors.green, fontSize: 18.0),),),Copy the code

Since the RotatedBox is applied to the layout stage, the widget is rotated 90 degrees (not just the content), and the decoration is applied to the actual space occupied by the widget, so it looks like the image above. You can compare this to the previous transform.rotate example

Matrix4

A 4D Transform matrix, a Transform uses Matrix4 to Transform its child widgets

// 4 x 4 matrix
factory Matrix4(double arg0, double arg1, double arg2, double arg3, double arg4, double arg5, double arg6, double arg7, double arg8, double arg9, double arg10, double arg11, double arg12, double arg13, double arg14, double arg15)

// Set a new matrix
factory Matrix4.columns(Vector4 arg0, Vector4 arg1, Vector4 arg2, Vector4 arg3)

// Combine translation, rotation and scaling to form a new transformation matrix
factory Matrix4.compose(Vector3 translation, Quaternion rotation, Vector3 scale)

// Copy a 4*4 tensor (matrix)
factory Matrix4.copy(Matrix4 other)

Vector3(double x, double y, double z)
factory Matrix4.diagonal3(Vector3 scale)

// Scale matrix, just with different parameters
factory Matrix4.diagonal3Values(double x, double y, double z)


Matrix4.fromBuffer(ByteBuffer buffer, int offset)

// Construct Matrix4 using the given Float64List
Matrix4.fromFloat64List(Float64List _m4storage)

// Convert a 16-bit one-dimensional array into a 4*4 matrix
factory Matrix4.fromList(List<double> values)

// Restore the original state, which is the 4*4 identity matrix
factory Matrix4.identity()

// Take the opposite matrix
factory Matrix4.inverted(Matrix4 other)

// Merge the product of two 4-dimensional vectors
factory Matrix4.outer(Vector4 u, Vector4 v)

// Rotate around the X-axis
factory Matrix4.rotationX(double radians)

// Rotate around the Y axis
factory Matrix4.rotationY(double radians)

// Rotate around the z-axis
factory Matrix4.rotationZ(double radians)

// Contort transform
factory Matrix4.skew(double alpha, double beta)

// Along the X-axis
factory Matrix4.skewX(double alpha)

// Along the Y-axis
factory Matrix4.skewY(double beta)

// Move the matrix
factory Matrix4.translation(Vector3 translation)

// Move the matrix with different parameters
factory Matrix4.translationValues(double x, double y, double z)

// a 4*4 tensor with all zeros
factory Matrix4.zero()
Copy the code

Container

  • ContainerIs a container classwidgetIt doesn’t correspond to specificRenderObject, it isDecoratedBox,ConstrainedBox,Transform,Padding,AlignEtc.widgetA composite widget of
  • So we only have to go through oneContainerYou can achieve scenes that need to be decorated, transformed, and restricted at the same time
  • The following isContainerRelated definitions of
Container({
    Key key,
    // To its way
    this.alignment,
    / / padding
    this.padding,
    // Background color
    Color color,
    // Background decoration
    Decoration decoration,
    // Foreground decoration
    this.foregroundDecoration,
    double width,
    double height,
    // Constraints on the size of the container
    BoxConstraints constraints,
    // The container margin, EdgeInsets
    this.margin,
    // Set the transformation matrix
    this.transform,
    this.child,
})
Copy the code
  • The size of the container can be passedwidth,heightProperty, can also be specified byconstraintsTo specify that, if both exist,width,heightIs preferred. In factContainerInternal will be based onwidth,heightTo generate aconstraints
  • coloranddecorationIs mutually exclusive, in fact, when specifiedcolorWhen,ContainerWill automatically create onedecoration

Using the instance

Use it to achieve the following effects

Container(
  margin: EdgeInsets.only(top: 50.0, left: 120.0), // Fill the container
  constraints: BoxConstraints.tightFor(width: 200.0, height: 150.0), // Card size
  decoration: BoxDecoration(// Background decoration
      gradient: RadialGradient( // Background radial gradient
          colors: [Colors.red, Colors.orange],
          center: Alignment.topLeft,
          radius: 98.
      ),
      boxShadow: [ // Card shadow
        BoxShadow(
            color: Colors.black54,
            offset: Offset(2.0.2.0),
            blurRadius: 4.0
        )
      ]
  ),
  transform: Matrix4.rotationZ(2.), // The card tilts
  alignment: Alignment.center, // The text inside the card is centered
  child: Text( // The card text
    "5.20", style: TextStyle(color: Colors.white, fontSize: 40.0),),);Copy the code

reference

  • Flutter container Widget– Chinese Version
  • Flutter website

Please scan the following wechat official account and subscribe to my blog!