[actual combat] positioning decorative weight components and histogram cases

Time:2021-10-22

[actual combat] positioning decorative weight components and histogram cases

Lao Meng‘s introduction: there are such components in the fluent, which are used to locate, decorate and control sub components, such asContainer(positioning, decoration)Expanded(Extended)SizedBox(fixed size)AspectRatio(aspect ratio)FractionallySizedBox(percentage of parent component). These components are frequently used. They are introduced one by one below. Finally, the actual cases in the project are given to get familiar with their usage.
[actual combat] series of articles address:http://laomengit.com/guide/introduction/mobile_system.html

Container

ContainerIs one of the most commonly used components. It is a single container component, that is, it can only contain one sub component, which is used to decorate and locate sub components, such as setting background color, shape, etc.

The simplest usage is as follows:

Container(
    Child: text ('lao Meng '),
 )

The subcomponents will not change in appearance:
[actual combat] positioning decorative weight components and histogram cases

Set background color:

Container(
    color: Colors.blue,
    Child: text ('lao Meng '),
)

[actual combat] positioning decorative weight components and histogram cases

Set inner margin(padding)And outer margin(margin )

Container(
      color: Colors.blue,
      child: Container(
        margin: EdgeInsets.all(10),
        padding: EdgeInsets.all(20),
        color: Colors.red,
        Child: text ('lao Meng '),
      ),
    )

The effects are as follows:
[actual combat] positioning decorative weight components and histogram cases

decorationProperty to set the background color, shape, etc. of the subcomponent. Set the background to round and the color to blue:

Container(
  Child: text ('lao Meng, focus on sharing flutter technology and applications'),
  decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.blue),
)

[actual combat] positioning decorative weight components and histogram cases

By default, the diameter of the circle is equal toContainerThe length of the narrow side is equivalent to drawing an inscribed circle in a rectangle.

The above situation is obviously not what we want to see. We want the background to be a rounded rectangle:

Container(
        Child: text ('lao Meng, focus on sharing flutter technology and applications'),
        padding: EdgeInsets.symmetric(horizontal: 10),
        decoration: BoxDecoration(
            shape: BoxShape.rectangle,
            borderRadius: BorderRadius.all(Radius.circular(20)),
            color: Colors.blue),
      )

[actual combat] positioning decorative weight components and histogram cases

In addition to the background, we can set the border effect. The code is as follows:

Container(
        Child: text ('lao Meng, focus on sharing flutter technology and applications'),
        padding: EdgeInsets.symmetric(horizontal: 10),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(12),
          border: Border.all(
            color: Colors.blue,
            width: 2,
          ),
        ),
      )

[actual combat] positioning decorative weight components and histogram cases

Create fillet and circle pictures:

Container(
      height: 200,
      width: 200,
      decoration: BoxDecoration(
        image:  DecorationImage(
          image: NetworkImage(
              'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'),
          fit: BoxFit.cover,
        ),
        border: Border.all(
          color: Colors.blue,
          width: 2,
        ),
        borderRadius: BorderRadius.circular(12),
      ),
    )

[actual combat] positioning decorative weight components and histogram cases
Change its shape to circular, and the code is as follows:

Container(
      height: 200,
      width: 200,
      decoration: BoxDecoration(
        image: DecorationImage(
          image: NetworkImage(
              'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'),
          fit: BoxFit.cover,
        ),
        border: Border.all(
          color: Colors.blue,
          width: 2,
        ),
        shape: BoxShape.circle,
      ),
    )

[actual combat] positioning decorative weight components and histogram cases

Set the alignment to center, the background color to blue, and the code is as follows:

Container(
        color: Colors.blue,
        Child: text ('lao Meng, a programmer with attitude '),
        alignment: Alignment.center,
      )

[actual combat] positioning decorative weight components and histogram cases

Note: after setting the alignment, the container will be filled with its parent controls, which is equivalent to that in Androidmatch_parent

AlignmentCommon locations have been encapsulated,

[actual combat] positioning decorative weight components and histogram cases

You can know its location by name. Here we will introduce other locations, such as 1 / 4 from the upper left corner:

Container(
  alignment: Alignment(-.5,-.5),
  Child: text ('lao Meng, focus on sharing flutter technology and applications'),
)

Therefore, there is a very important coordinate system. The alignment coordinate system is as follows:

[actual combat] positioning decorative weight components and histogram cases

The center of the component is the coordinate origin.

Set fixed width and height properties:

Container(
        color: Colors.blue,
        Child: text ('lao Meng, focus on sharing flutter technology and applications'),
        alignment: Alignment.center,
        height: 60,
        width: 250,
      )

[actual combat] positioning decorative weight components and histogram cases

adoptconstraintsProperty to set the maximum / minimum width and height to determine the size. If not set, the default minimum width and height is 0, and the maximum width and height is infinite (double. Infinity). The constraint width code is as follows:

Container(
        color: Colors.blue,
        Child: text ('lao Meng, focus on sharing flutter technology and applications'),
        alignment: Alignment.center,
        constraints: BoxConstraints(
          maxHeight: 100,
          maxWidth: 300,
          minHeight: 100,
          minWidth: 100,
        ),
      )

[actual combat] positioning decorative weight components and histogram cases

The container can be rotated, translated and scaled by transform. The rotation code is as follows:

Container(
        color: Colors.blue,
        Child: text ('lao Meng, focus on sharing flutter technology and applications'),
        alignment: Alignment.center,
        height: 60,
        width: 250,
        transform: Matrix4.rotationZ(0.5),
      )

Note: the matrix4. Rotationz() parameter is in radians, not angles

[actual combat] positioning decorative weight components and histogram cases

SizedBox

SizedBoxIt is a component with fixed width and height. It directly specifies the specific width and height. The usage is as follows:

SizedBox(
        height: 60,
        width: 200,
        child: Container(
          color: Colors.blue,
          alignment: Alignment.center,
          Child: text ('lao Meng, focus on sharing flutter technology and applications'),
        ),
      )

[actual combat] positioning decorative weight components and histogram cases

Set the size to infinity as follows:

SizedBox(
  height: double.infinity,
  width: double.infinity,
  ...
)

Although infinity is set, will the child controls be infinitely long? No, no, the child control will still be constrained by the parent component and will expand to the size of the parent component. There is another convenient way to set this method:

SizedBox.expand(
  Child: text ('lao Meng, focus on sharing flutter technology and applications'),
)

Sizedbox can have no sub components, but it still takes up space. Therefore, sizedbox is very suitable for controlling the gap between two components. The usage is as follows:

Column(
          children: <Widget>[
            Container(height: 30,color: Colors.blue,),
            SizedBox(height: 30,),
            Container(height: 30,color: Colors.red,),
          ],
        )

[actual combat] positioning decorative weight components and histogram cases

AspectRatio

AspectRatioIt is a component with fixed aspect ratio. The usage is as follows:

Container(
        height: 300,
        width: 300,
        color: Colors.blue,
        alignment: Alignment.center,
        child: AspectRatio(
          aspectRatio: 2 / 1,
          child: Container(color: Colors.red,),
        ),
      )

Aspectratio is the aspect ratio. It can be written directly in the form of fraction or decimal. However, it is recommended to write it in the form of fraction, which is more readable. The effects are as follows:

[actual combat] positioning decorative weight components and histogram cases

FractionallySizedBox

FractionallySizedBoxIt is a component relative to the size of the parent component, for example, accounting for 70% of the parent component:

Container(
  height: 200,
  width: 200,
  color: Colors.blue,
  child: FractionallySizedBox(
    widthFactor: .8,
    heightFactor: .3,
    child: Container(
      color: Colors.red,
    ),
  ),
)

[actual combat] positioning decorative weight components and histogram cases

Use the alignment parameter to control the display position of sub components. The default is center. The usage is as follows:

FractionallySizedBox(
  alignment: Alignment.center,
  ...
)

Weight component

ExpandedFlexibleandSpacerAre components with weight attributes that can control how the child controls of row, column and flex are laid out.

The flexible component can control the child controls of row, column and flex to occupy the parent component. For example, there are three child components in row, the width on both sides is 100, and the middle occupies the remaining space. The code is as follows:

Row(
      children: <Widget>[
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
        Flexible(
            child: Container(
              color: Colors.red,
              height: 50,
            )
        ),
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
      ],
    )

[actual combat] positioning decorative weight components and histogram cases

There are still three sub components. The first one accounts for 1 / 6, the second one accounts for 2 / 6, and the third one accounts for 3 / 6. The code is as follows:

Column(
      children: <Widget>[
        Flexible(
          flex: 1,
          child: Container(
            color: Colors.blue,
            alignment: Alignment.center,
            child: Text('1 Flex/ 6 Total',style: TextStyle(color: Colors.white),),
          ),
        ),
        Flexible(
          flex: 2,
          child: Container(
            color: Colors.red,
            alignment: Alignment.center,
            child: Text('2 Flex/ 6 Total',style: TextStyle(color: Colors.white),),
          ),
        ),
        Flexible(
          flex: 3,
          child: Container(
            color: Colors.green,
            alignment: Alignment.center,
            child: Text('3 Flex/ 6 Total',style: TextStyle(color: Colors.white),),
          ),
        ),
      ],
    )

[actual combat] positioning decorative weight components and histogram cases

Proportion of sub components = current sub control flex/Sum of all sub components flex.

In flexiblefitThe parameter indicates how to fill the remaining space. The description is as follows:

  • Tight: the remaining space must be (forced) filled.
  • Loose: fill the remaining space as much as possible, but you can not fill it.

These two don’t seem to be easy to understand. What does it mean to fill the remaining space as large as possible? When will it be filled? Take the following example:

Row(
      children: <Widget>[
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
        Flexible(
            child: Container(
              color: Colors.red,
              height: 50,
              child: Text('Container',style: TextStyle(color: Colors.white),),
            )
        ),
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
      ],
    )

[actual combat] positioning decorative weight components and histogram cases

This code adds a text sub control to the red container in the middle based on the top code. At this time, the red container is no longer full of space, and then add an alignment to the container. The code is as follows:

Row(
      children: <Widget>[
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
        Flexible(
            child: Container(
              color: Colors.red,
              height: 50,
              alignment: Alignment.center,
              child: Text('Container',style: TextStyle(color: Colors.white),),
            )
        ),
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
      ],
    )

[actual combat] positioning decorative weight components and histogram cases
At this time, the remaining space is filled.

Do you remember how the container component is resized? By default, the container fits the size of the child control, but when the alignment is set, the container will fill the parent component, so whether to fill the remaining space depends on whether the child component needs to fill the parent component.

If the flexible subassembly is changed from container to outlinbutton, the code is as follows:

Row(
      children: <Widget>[
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
        Flexible(
          child: OutlineButton(
            child: Text('OutlineButton'),
          ),
        ),
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
      ],
    )

The outlinebutton normally does not fill the parent component, so the final effect should not fill the remaining space:
[actual combat] positioning decorative weight components and histogram cases

Let’s introduce another weight componentExpanded, the source code is as follows:

class Expanded extends Flexible {
  /// Creates a widget that expands a child of a [Row], [Column], or [Flex]
  /// so that the child fills the available space along the flex widget's
  /// main axis.
  const Expanded({
    Key key,
    int flex = 1,
    @required Widget child,
  }) : super(key: key, flex: flex, fit: FlexFit.tight, child: child);
}

The expanded inheritance word is flexible, and the fit parameter is fixed toFlexFit.tightThat is, expanded must (forcibly) fill the remaining space. The outline button above can be used directly to fill the remaining space:

Row(
      children: <Widget>[
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
        Expanded(
          child: OutlineButton(
            child: Text('OutlineButton'),
          ),
        ),
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
      ],
    )

[actual combat] positioning decorative weight components and histogram cases

SpacerIt is also a weight component. The source code is as follows:

@override
Widget build(BuildContext context) {
  return Expanded(
    flex: flex,
    child: const SizedBox.shrink(),
  );
}

The essence of spacer is also the implementation of expanded. The difference between expanded and expanded is that expanded can set child controls, and the size of the child controls of spacer is 0. Therefore, spacer is suitable for opening the gap between the child controls of row, column and flex. The usage is as follows:

Row(
  children: <Widget>[
    Container(width: 100,height: 50,color: Colors.green,),
    Spacer(flex: 2,),
    Container(width: 100,height: 50,color: Colors.blue,),
    Spacer(),
    Container(width: 100,height: 50,color: Colors.red,),
  ],
)

[actual combat] positioning decorative weight components and histogram cases

The three weights are summarized below

  • Spacer is implemented through expanded, which inherits from flexible.
  • It is more convenient to fill the remaining space and use expanded directly.
  • Spacer is used to open the gap between the sub components of row, column and flex.

Imitation Nuggets – my effect

Let’s see the effect first:

[actual combat] positioning decorative weight components and histogram cases

Don’t panic when you get the effect drawing (take out your mobile phone to take photos and send a circle of friends). The layout of each line in the whole list is basically the same, so write the effect of one line first:

class _SettingItem extends StatelessWidget {
  const _SettingItem(
      {Key key, this.iconData, this.iconColor, this.title, this.suffix})
      : super(key: key);

  final IconData iconData;
  final Color iconColor;
  final String title;
  final Widget suffix;

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 45,
      child: Row(
        children: <Widget>[
          SizedBox(
            width: 30,
          ),
          Icon(iconData,color: iconColor,),
          SizedBox(
            width: 30,
          ),
          Expanded(
            child: Text('$title'),
          ),
          suffix,
          SizedBox(
            width: 15,
          ),
        ],
      ),
    );
  }
}

The final style of the message center is different from that of other lines. The components with red background are encapsulated separately:

class _NotificationsText extends StatelessWidget {
  final String text;

  const _NotificationsText({Key key, this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 10),
      decoration: BoxDecoration(
          shape: BoxShape.rectangle,
          borderRadius: BorderRadius.all(Radius.circular(50)),
          color: Colors.red),
      child: Text(
        '$text',
        style: TextStyle(color: Colors.white),
      ),
    );
  }
}

Gray suffix component:

class _Suffix extends StatelessWidget {
  final String text;

  const _Suffix({Key key, this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Text(
      '$text',
      style: TextStyle(color: Colors.grey.withOpacity(.5)),
    );
  }
}

Combine these encapsulated components:

class SettingDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        _SettingItem(
          iconData: Icons.notifications,
          iconColor: Colors.blue,
          Title: 'message center',
          suffix: _NotificationsText(
            text: '2',
          ),
        ),
        Divider(),
        _SettingItem(
          iconData: Icons.thumb_up,
          iconColor: Colors.green,
          Title: 'I liked it',
          suffix: _Suffix(
            Text: '121 articles',
          ),
        ),
        Divider(),
        _SettingItem(
          iconData: Icons.grade,
          iconColor: Colors.yellow,
          Title: 'collection',
          suffix: _Suffix(
            Text: '2',
          ),
        ),
        Divider(),
        _SettingItem(
          iconData: Icons.shopping_basket,
          iconColor: Colors.yellow,
          Title: 'purchased booklet',
          suffix: _Suffix(
            Text: '100',
          ),
        ),
        Divider(),
        _SettingItem(
          iconData: Icons.account_balance_wallet,
          iconColor: Colors.blue,
          Title: 'my wallet',
          suffix: _Suffix(
            Text: '100000',
          ),
        ),
        Divider(),
        _SettingItem(
          iconData: Icons.location_on,
          iconColor: Colors.grey,
          Title: 'read articles',
          suffix: _Suffix(
            Text: '1034 articles',
          ),
        ),
        Divider(),
        _SettingItem(
          iconData: Icons.local_offer,
          iconColor: Colors.grey,
          Title: 'label management',
          suffix: _Suffix(
            Text: '27',
          ),
        ),
      ],
    );
  }
}

That’s it.

Histogram

Let’s take a look at the following effects:

[actual combat] positioning decorative weight components and histogram cases

The content of animation will be described in detail in later chapters. This effect is divided into three parts:

  1. Axis, left and bottom black lines.
  2. Rectangular histogram.
  3. Animation control part.

The realization of coordinate axis is as follows:

class _Axis extends StatelessWidget {
  final Widget child;

  const _Axis({Key key, this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        border: Border(
          left: BorderSide(color: Colors.black, width: 2),
          bottom: BorderSide(color: Colors.black, width: 2),
        ),
      ),
      child: child,
    );
  }
}

[actual combat] positioning decorative weight components and histogram cases

Single histogram implementation:

class _Cylinder extends StatelessWidget {
  final double height;
  final double width;
  final Color color;

  const _Cylinder({Key key, this.height, this.width, this.color})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      duration: Duration(seconds: 1),
      height: height,
      width: width,
      color: color,
    );
  }
}

Generate multiple histograms:

final double _width = 20.0;
List<double> _heightList = [60.0, 80.0, 100.0, 120.0, 140.0];

Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    crossAxisAlignment: CrossAxisAlignment.end,
    children: List.generate(_heightList.length, (index) {
      return _Cylinder(
        height: _heightList[index],
        width: _width,
        color: Colors.primaries[index % Colors.primaries.length],
      );
    }))

[actual combat] positioning decorative weight components and histogram cases

Merge this and change the height of each histogram:

class CylinderChart extends StatefulWidget {
  @override
  _CylinderChartState createState() => _CylinderChartState();
}

class _CylinderChartState extends State<CylinderChart> {
  final double _width = 20.0;
  List<double> _heightList = [60.0, 80.0, 100.0, 120.0, 140.0];

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        height: 200,
        width: 250,
        child: Stack(
          children: <Widget>[
            _Axis(),
            Positioned.fill(
              left: 5,
              right: 5,
              child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: List.generate(_heightList.length, (index) {
                    return _Cylinder(
                      height: _heightList[index],
                      width: _width,
                      color: Colors.primaries[index % Colors.primaries.length],
                    );
                  })),
            ),
            Positioned(
              top: 0,
              left: 30,
              child: OutlineButton(
                Child: text ('reverse '),
                onPressed: () {
                  setState(() {
                    _heightList = _heightList.reversed.toList();
                  });
                },
              ),
            )
          ],
        ),
      ),
    );
  }
}

Done.

communication

Laomeng fluent blog address (330 controls usage):http://laomengit.com

Welcome to Flutter exchange group (WeChat: laomengit) and official account [Lao Meng Flutter]:

[actual combat] positioning decorative weight components and histogram cases [actual combat] positioning decorative weight components and histogram cases