(Original) Basic introduction to Flutter: various common container components

Preface

The previous blog mainly talked about Flutter's Shape implementation.
Getting started with Flutter: Achieving various Shape effects.
Today I will mainly talk about some container components commonly used in Flutter.
There are many components in Flutter, and they are classified in different ways.
For example, they can be divided into stateful group prices. And stateless components
can be divided into container components, functional components, etc.
Taking functional components as an example,
there is a TextView used to display text,
an Image
to display a list, a ListView, etc.
However, today we mainly talk about some container components.
So what are container components? ?
Container components refer to components that can accommodate subordinate components (one or more) and
are used as independent components when used.
For example, the Row component, the ListView component just mentioned, etc.
The main focus of the container components we are talking about today
is to talk about some of the functions they support.
By introducing the meaning of the parameters they need to pass in,
we can understand the functions of these containers more clearly ,
rather than just introducing the usage.
Of course, here we also select some commonly used and Let’s introduce the powerful components
and let’s start officially.

Various containers

Container

Container will be the most powerful and commonly used single-container control we use in Flutter development.
It can implement a series of functions such as decoration, positioning, background color, alignment, transformation, cropping, etc.
Let’s take a look at its structure first. method

  Container({
    
    
    super.key,
    this.alignment,
    this.padding,
    this.color,
    this.decoration,
    this.foregroundDecoration,
    double? width,
    double? height,
    BoxConstraints? constraints,
    this.margin,
    this.transform,
    this.transformAlignment,
    this.child,
    this.clipBehavior = Clip.none,
  })

As you can see, there are many optional input parameters that can be passed in here. We will introduce them one by one.

alignment

Alignment, you can set the alignment of subcomponents.
Examples are as follows:

  
  Widget build(BuildContext context) {
    
    
    return Container(
      width: 200,
      height: 200,
      alignment: Alignment.center,
      color: Colors.grey,
      child: Text('文字控件'),
    );
  }

If you click on Alignment.center, you will see that it is actually
center = Alignment(0.0, 0.0);
similarly:
topLeft = Alignment(-1.0, -1.0);
bottomRight = Alignment(1.0, 1.0);
This way we know:
Alignment The first parameter of the construction method represents the left and right positions, and the second parameter represents the upper and lower positions.
0 represents the center point, -1 represents the leftmost/topmost, 1 represents the rightmost/bottommost
. For example: Alignment(0,1) means left and right center, Align bottom,
that is:
bottomCenter = Alignment(0.0, 1.0);

padding & margin

padding is the inner margin and margin is the outer margin
. For example:

  
  Widget build(BuildContext context) {
    
    
    return Container(
      width: 200,
      height: 200,
      padding: EdgeInsets.all(10),
      margin: EdgeInsets.only(top: 10),
      alignment: Alignment.topLeft,
      color: Colors.grey,
      child: Text('文字控件'),
    );
  }

The effect is:
Insert image description here
Note here that padding & margin need to be passed in all of the EdgeInsetsGeometry type.
The EdgeInsetsGeometry abstract class has two subclasses: EdgeInsets and EdgeInsetsDirectional.
It can be understood that this class is used to set some spacing.

decoration & foregroundDecoration

foregroundDecoration is the decoration drawn in front of the child. If decoration is set, the foregroundDecoration style will be superimposed on the decoration style at this time.
For decorators, you can read my special blog on
Flutter Basics in this series: Decorator Decoration

constraints

constraints is a BoxConstraints type
mainly used to control the minimum width and height of sub-controls, as follows:

  Container(
    width: 200,
    height: 200,
    color: Colors.grey,
    alignment: Alignment.center,
    child: Container(
      child: Text('文字控件'),
      constraints: BoxConstraints(minWidth: 100,minHeight: 100),
      color: Colors.red,
    ),
  );

After limiting the minimum width and height to 100, the background size of the text becomes 100, instead of tightly wrapping the text before.
Insert image description here

transform & transformAlignment

Transform mainly uses a 4*4 transformation matrix to transform sub-components.
The effects that can be achieved are: oblique cutting, scaling, translation, rotation, perspective, etc.
transformAlignment is the position of the transformation.
The type and alignment of this parameter are the alignment parameters. The types are the same.
They are all AlignmentGeometry types.
The default is Alignment.topLeft
. For example, we can rotate the Z axis based on the center position of the component:

  Container(
  width: 200,
  height: 200,
  transformAlignment: Alignment.center,//变换位置:中心点旋转
  transform: Matrix4.rotationZ(-0.5),//z轴旋转
  color: Colors.grey,
  alignment: Alignment.center,
  child: Text('文字控件'),
);

The effect is as follows:
Insert image description here

clipBehavior

clipBehavior is the cutting method for the edge of the component content. When the component content overflows, you can choose different cutting methods.
Insert image description here

color & width &height & child

Color is used to set the filling color of the container. Just pass in the double type for width and height.
Child is naturally a sub-component.
These simple ones will not be demonstrated.

Padding

Padding is mainly used to add inner margins to sub-components. Please refer to the padding of Container.

Align

Align is used to set the alignment of subcomponents. Please refer to Container's alignment.

ConstrainedBox

ConstrainedBox is used to set the minimum width and height. You need to pass in a BoxConstraints type. Please refer to the constraints of Container.

DecoratedBox

DecoratedBox can draw some decorations (Decoration), such as background, border, gradient, etc., before (or after) its child components are drawn.
Its constructor is as follows:

  const DecoratedBox({
    
    
    super.key,
    required this.decoration,
    this.position = DecorationPosition.background,
    super.child,
  })

The position attribute is mainly used to set the decoration position, which
is divided into:
(DecorationPosition.foreground) foreground, (DecorationPosition.background) background

Transform

Transform is mainly used to add transformation effects to sub-components. Please refer to Container's transform.

RotatedBox

Container for rotating child components

  const RotatedBox({
    
    
    super.key,
    required this.quarterTurns,
    super.child,
  })

quarterTurns represents the number of rotations. The degree of each rotation can only be an integer multiple of 90 degrees.
Therefore, the angle of rotation of the RotatedBox can only be an integer multiple of 90 degrees.

Clip cutting related components

Clip related components are mainly used to clip sub-components, such as:
ClipOval: When the sub-component is a square, it is cut into a circle with an inner side; when it is a rectangle, it is cut into an ellipse with an inner side.
ClipRRect: The sub-component is cut into a rounded rectangle
. ClipRect: By default, the drawing content outside the layout space of the sub-component is clipped (the overflow part is clipped)
ClipPath: clip according to the customized path.
Let’s see a specific example:

class _ClipWidget extends StatelessWidget {
    
    
  final Image photo = Image.network(
    'https://tse1.mm.bing.net/th/id/OET.5272002b31e349ca8b7f061d2d17466f?w=135&h=272&c=7&rs=1&o=5&dpr=2&pid=1.9',
    height: 100,
    width: 100,
    fit: BoxFit.cover,
  );

  
  Widget build(BuildContext context) => MaterialApp(
    home: Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            photo,
            const SizedBox(
              height: 20,
            ),
            ClipOval(
              child: photo,
            ),
            const SizedBox(
              height: 20,
            ),
            ClipRRect(
              child: photo,
              borderRadius: const BorderRadius.all(Radius.circular(20)),
            ),
            const SizedBox(
              height: 20,
            ),
            Container(
              color: Colors.red,
              child: Row(
                children: [
                  Align(
                    alignment: Alignment.centerRight,
                    widthFactor: 0.5,
                    child: ClipRect(
                      child: photo,
                    ),
                  ),
                  const Text('我是文本')
                ],
              ),
            ),
          ],
        ),
      ),
    ),
  );
}

The effect is as follows:
Insert image description here

FittedBox

When the aspect ratio of the child component is different from the aspect ratio of the parent component, we stretch or fill the parent component proportionally. In this case, we can use FittedBox

  Container(
    height: 200,
    width: 200,
    color: Colors.green,
    child: FittedBox(
      fit: BoxFit.contain,
      child: Container(
        height: 50,
        width: 80,
        color: Colors.red,
      ),
    ),
  );

As shown in the figure:
Insert image description here
The fit parameter represents the filling method of the child control, and the description is as follows:
fill: fill the parent component, and the aspect ratio changes.
contain: Stretch proportionally, but the child control cannot exceed the parent control.
cover: Make it as small as possible and stretch it proportionally to fill the parent control.
fitWidth: Stretch proportionally, the width fills the parent control.
fitHeight: Stretch proportionally, the height fills the parent control.
none: By default, the child control is centered, no stretching is performed, and the part beyond the parent control is cropped.
scaleDown: When the child control is Image and is reduced, it is the same as contain, otherwise it is the same as none.

card

It is used to make sub-components into card-like styles.
It can also be used to achieve some Shape effects.
The main attributes are as follows:

  const Card({
    
    
    super.key,
    this.color,//背景色
    this.shadowColor,//阴影颜色
    this.surfaceTintColor,
    this.elevation,//阴影高度
    this.shape,
    this.borderOnForeground = true,//是否在 child 前绘制 border,默认为 true
    this.margin,
    this.clipBehavior,
    this.child,
    this.semanticContainer = true,
  })

You can see that most of them are similar to Container.

Row & Column

These two are similar to Android's LinearLayout.
Their children attribute can be passed in an array of subcomponents.
Row is for horizontal layout of subcomponents.
Column is for vertical layout of subcomponents.

Wrap & Stack

Wrap flow layout
Stack is similar to the frame layout FrameLayout in Android

Scaffold

Scaffold translates as scaffolding.
It is actually a template component provided to us to facilitate us to quickly build pages.

  const Scaffold({
    
    
    super.key,
    this.appBar,
    this.body,
    this.floatingActionButton,
    this.floatingActionButtonLocation,
    this.floatingActionButtonAnimator,
    this.persistentFooterButtons,
    this.persistentFooterAlignment = AlignmentDirectional.centerEnd,
    this.drawer,
    this.onDrawerChanged,
    this.endDrawer,
    this.onEndDrawerChanged,
    this.bottomNavigationBar,
    this.bottomSheet,
    this.backgroundColor,
    this.resizeToAvoidBottomInset,
    this.primary = true,
    this.drawerDragStartBehavior = DragStartBehavior.start,
    this.extendBody = false,
    this.extendBodyBehindAppBar = false,
    this.drawerScrimColor,
    this.drawerEdgeDragWidth,
    this.drawerEnableOpenDragGesture = true,
    this.endDrawerEnableOpenDragGesture = true,
    this.restorationId,
  })

Scaffold has many attributes. Let’s pick some commonly used ones.
AppBar: The top bar of the page is a PreferredSizeWidget abstract class. You can choose implementation classes such as AppBar and TabBar as the top bar.
Body: The main part. Put a subcomponent to
bottomNavigationBar. : Bottom component, generally used to implement the button switching function at the bottom of the home page
drawer & endDrawer: Left and right side sliding components
backgroundColor: Background color
floatingActionButton: Floating button
floatingActionButtonLocation: Floating button location
Write a Scaffold-wrapped page below
to implement some basic demonstration functions:

import 'package:flutter/material.dart';
void main() {
    
    
  runApp(MaterialApp(
    title: "首页",
    home: CustomScaffold(),
  ));
}

class CustomScaffold extends StatefulWidget {
    
    
  const CustomScaffold({
    
    Key? key}) : super(key: key);

  
  State<StatefulWidget> createState() => _CustomScaffoldState();
}

// AppBar 默认的实例,有状态
class _CustomScaffoldState extends State with SingleTickerProviderStateMixin {
    
    
  final List<String> tabs = const ['实时新闻', '今日头条', '经济', '股票', '体育竞技', '国际风云'];
  int _position = 0;
  final Map<String,IconData> iconsMap = {
    
    
    "首页": Icons.home,
    "动态": Icons.toys,
    "收藏": Icons.favorite,
    "图鉴": Icons.class_,
    "我的": Icons.account_circle,
  };
  final List<Color> _colors = [
    Colors.blue,
    Colors.red,
    Colors.yellow,
    Colors.green,
    Colors.purple,
  ];

  late TabController _tabController;

  
  void initState() {
    
    
    super.initState();
    _tabController = TabController(vsync: this, length: tabs.length);
  }

  
  void dispose() {
    
    
    _tabController.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    
    
    return SizedBox(
      width: MediaQuery.of(context).size.width,
      height: MediaQuery.of(context).size.height - 300,
      child: Scaffold(
        floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
        floatingActionButton: FloatingActionButton(
          child: const Icon(Icons.add),
          onPressed: () {
    
    },
        ),
        drawer: _buildLeftDrawer(),
        endDrawer: _buildLeftDrawer(),
        appBar: AppBar(
          title: const Text('首页'),
          backgroundColor: Colors.blue,
          centerTitle: true,
          bottom: _buildTabBar(),
        ),
        body: _buildTableBarView(),
        bottomNavigationBar: _buildBottomNavigationBar(),
      ),
    );
  }

  Drawer _buildLeftDrawer() => Drawer(
    elevation: 1,
    child: Image.network(
      'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201907%2F22%2F20190722235951_J3aVw.thumb.1000_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1684313785&t=63178f27b92b3cfc174d8354fe203c94',
      fit: BoxFit.cover,
    ),
  );

  PreferredSizeWidget _buildTabBar() => TabBar(
    isScrollable: true,
    controller: _tabController,
    indicatorColor: Colors.orangeAccent,
    tabs: tabs.map((e) => Tab(text: e)).toList(),
  );

  Widget _buildBottomNavigationBar() => BottomNavigationBar(
    onTap: (position) => setState(() => _position = position),
    currentIndex: _position,
    elevation: 1,
    backgroundColor: Colors.white,
    iconSize: 25,
    selectedLabelStyle: const TextStyle(fontWeight: FontWeight.bold),
    showUnselectedLabels: false,
    showSelectedLabels: true,
    items: iconsMap.keys
        .map((key) => BottomNavigationBarItem(
        label: key,
        icon: Icon(iconsMap[key]),
        backgroundColor: _colors[_position]))
        .toList(),
  );

  Widget _buildTableBarView() => TabBarView(
      controller: _tabController,
      children: tabs
          .map((e) => Center(
          child: Text(
            e,
            style: const TextStyle(color: Colors.blue, fontSize: 20),
          )))
          .toList());
}

The effect is as follows:
Insert image description here

Data sharing

Finally, I recommend a good project to everyone: Most of the components of
Flutter_unit can be learned in this project . It not only has an introduction to the components, but also has real code and effect demonstrations.

There is also a website where you can learn more components:
Flutter | Lao Meng

Guess you like

Origin blog.csdn.net/Android_xiong_st/article/details/130156906