Flutter中Padding、Row 、Column 、Expanded 组件详解

2022-05-06 14:56:58 浏览数 (2)

1. Paddiing 组件

在 html 中常见的布局标签都可以使用 padding 属性,但是 Flutter 中很多 Widget 是没有 padding 属 性,这个时候我们可以用 Padding 组件处理容器与子元素直接的间距。

常见属性:

1. padding 内边距值;

2. child 子组件;

代码示例:

代码语言:javascript复制
import 'package:flutter/material.dart';

void main(){
    runApp(MyApp());
}
// 抽离成一个单独的组件
class MyApp extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
                // 导航条
                appBar:AppBar(title:Text('Flutter App')),
                // 主体
                body:HomeContent(),
            ),
            theme: ThemeData(primarySwatch:Colors.yellow),
        );
    }
}

// Padding内边距的使用
class HomeContent extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return  Padding(
            // 给整个容器右边添加内边距
            padding: EdgeInsets.fromLTRB(0,0,10,0),
            child: GridView.count(
                // 定义一行几列
                crossAxisCount:2,
                // 长宽比例
                childAspectRatio:1.7,
                children:<Widget>[
                    Padding(
                        // 定义左、上内边距
                        padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
                        // 子元素
                        child: Image.network("http://www.itying.com/images/flutter/1.png",fit: BoxFit.cover)
                    ),

                    Padding(
                        padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
                        child: Image.network("http://www.itying.com/images/flutter/2.png",fit: BoxFit.cover)
                    ),
                    Padding(
                        padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
                        child: Image.network("http://www.itying.com/images/flutter/3.png",fit: BoxFit.cover)
                    ),
                    Padding(
                        padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
                        child: Image.network("http://www.itying.com/images/flutter/4.png",fit: BoxFit.cover)
                    ),
                    Padding(
                        padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
                        child: Image.network("http://www.itying.com/images/flutter/3.png",fit: BoxFit.cover)
                    ),
                    Padding(
                        padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
                        child: Image.network("http://www.itying.com/images/flutter/2.png",fit: BoxFit.cover)
                    ),
                    Padding(
                        padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
                        child: Image.network("http://www.itying.com/images/flutter/1.png",fit: BoxFit.cover)
                    ),
                    Padding(
                        padding: EdgeInsets.fromLTRB(10, 10, 0, 0),
                        child: Image.network("http://www.itying.com/images/flutter/4.png",fit: BoxFit.cover)
                    )
                ],
            )
        );
    }
}

效果图如下:

需要注意的是,以上图片的间隙由内外两层内边距组合使用而得出来的。

2. Row 组件

Row 组件主要用于需要水平布局的情况。

常见属性:

1. mainAxisAlignment 主轴的组件对齐方式;

2. crossAxisAlignment 次轴的组件对齐方式;

3. children 组件子元素;

代码示例:

代码语言:javascript复制
import 'package:flutter/material.dart';

void main(){
    runApp(MyApp());
}
// 抽离成一个单独的组件
class MyApp extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
                // 导航条
                appBar:AppBar(title:Text('Flutter App')),
                // 主体
                body:HomeContent(),
            ),
            theme: ThemeData(primarySwatch:Colors.yellow),
        );
    }
}
// Row水平布局组件的使用
class HomeContent extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return Container(
            // 宽度
            width:500,
            // 高度
            height:500,
            // 背景颜色
            color:Colors.red,
            // 水平布局组件
            child: Row(
                // 定义水平对齐的方式,类似于CSS里的flex-decration
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                // 定义元素相对父容器的垂直对齐方式
                crossAxisAlignment: CrossAxisAlignment.center,
                // 子元素
                children: <Widget>[
                    // 调用自定义的图标组件传参
                    IconContainer(Icons.search,color:Colors.black,size:40.0),
                    IconContainer(Icons.home,color:Colors.green,size:40.0),
                    IconContainer(Icons.select_all,color:Colors.blue,size:40.0)
                ],
            )
        );
    }
}


// 定义传入图标的类
class IconContainer extends StatelessWidget{

    double size = 32.0;
    Color color = Colors.red;
    IconData icon;

    // 构造函数
    IconContainer(this.icon,{this.color,this.size});

    @override
    Widget build(BuildContext context) {
        return Container(
            // 宽度
            height:100.0,
            // 高度
            width:100.0,
            // 背景颜色
            color:this.color,
            // 子元素
            child:Center(
                child: Icon(this.icon,size:this.size,color:Colors.white)
            )
        );
    }
}

效果图如下:

3. Column组件

Column 组件主要用于需要垂直布局的情况。

常见属性:

1. mainAxisAlignment 主轴的组件对齐方式;

2. crossAxisAlignment 次轴的组件对齐方式;

3. children 组件子元素;

代码示例:

代码语言:javascript复制
import 'package:flutter/material.dart';

void main(){
    runApp(MyApp());
}
// 抽离成一个单独的组件
class MyApp extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
                // 导航条
                appBar:AppBar(title:Text('Flutter App')),
                // 主体
                body:HomeContent(),
            ),
            // 主题
            theme: ThemeData(primarySwatch:Colors.yellow),
        );
    }
}

// Column垂直布局组件的使用
class HomeContent extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return Container(
            // 宽度
            width:500,
            // 高度
            height:500,
            // 背景颜色
            color:Colors.red,
            // 垂直布局组件
            child: Column(
                // 定义垂直对齐的方式,类似于CSS里的flex-decration
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                // 定义元素相对父容器的水平对齐方式
                crossAxisAlignment: CrossAxisAlignment.center,
                // 子元素
                children: <Widget>[
                    // 调用自定义的图标组件传参
                    IconContainer(Icons.search,color:Colors.black,size:40.0),
                    IconContainer(Icons.home,color:Colors.green,size:40.0),
                    IconContainer(Icons.select_all,color:Colors.blue,size:40.0)
                ],
            )
        );
    }
}

效果图如下:

4. Expanded组件

Expanded 类似 Web 开发中的Flex布局,可以用在 Row 和 Column 布局中以定义该子组件所占的百分比。

常见属性:

1. flex 子组件占整个父组件比例;

2. child 子组件;

代码示例:

代码语言:javascript复制
import 'package:flutter/material.dart';

void main(){
    runApp(MyApp());
}
// 抽离成一个单独的组件
class MyApp extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
                // 导航条
                appBar:AppBar(title:Text('Flutter App')),
                // 主体
                body:HomeContent(),
            ),
            // 主题
            theme: ThemeData(primarySwatch:Colors.yellow),
        );
    }
}

// Expanded组件的使用,定义一行中每个元素的百分比
class HomeContent extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return  Row(
            // 子元素
            children: <Widget>[
                Expanded(
                    flex:1,
                    child:IconContainer(Icons.search,color:Colors.red,size:40.0),
                ), 
                Expanded(
                    flex:2,
                    child:IconContainer(Icons.home,color:Colors.black,size:40.0),
                ),
                Expanded(
                    flex:1,
                    child:IconContainer(Icons.select_all,color:Colors.green,size:40.0),
                ),
            ],
        );
    }
}


// 定义传入图标的类
class IconContainer extends StatelessWidget{

    double size = 32.0;
    Color color = Colors.red;
    IconData icon;

    // 构造函数
    IconContainer(this.icon,{this.color,this.size});

    @override
    Widget build(BuildContext context) {
        return Container(
            // 宽度
            height:100.0,
            // 高度
            width:100.0,
            // 背景颜色
            color:this.color,
            // 子元素
            child:Center(
                child: Icon(this.icon,size:this.size,color:Colors.white)
            )
        );
    }
}

效果图如下:

利用Expanded实现一个左侧固定,右侧自适应的布局。

代码语言:javascript复制
import 'package:flutter/material.dart';

void main(){
    runApp(MyApp());
}
// 抽离成一个单独的组件
class MyApp extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
                // 导航条
                appBar:AppBar(title:Text('Flutter App')),
                // 主体
                body:HomeContent(),
            ),
            // 主题
            theme: ThemeData(primarySwatch:Colors.yellow),
        );
    }
}
// Expanded组件实现左侧固定宽度,右侧自适应的布局
class HomeContent extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return  Row(
            // 子元素
            children: <Widget>[
                // 左侧组件固定宽度
                IconContainer(Icons.search,color:Colors.red,size:40.0),
                // 右侧组件自适应
                Expanded(
                    // 自适应时值为1即可
                    flex:1,
                    child:IconContainer(Icons.select_all,color:Colors.green,size:40.0),
                ),
            ],
        );
    }
}

// 定义传入图标的类
class IconContainer extends StatelessWidget{

    double size = 32.0;
    Color color = Colors.red;
    IconData icon;

    // 构造函数
    IconContainer(this.icon,{this.color,this.size});

    @override
    Widget build(BuildContext context) {
        return Container(
            // 宽度
            height:100.0,
            // 高度
            width:100.0,
            // 背景颜色
            color:this.color,
            // 子元素
            child:Center(
                child: Icon(this.icon,size:this.size,color:Colors.white)
            )
        );
    }
}

效果图如下:

5. 布局实例

实现下图的布局:

代码如下:

代码语言:javascript复制
import 'package:flutter/material.dart';

void main(){
    runApp(MyApp());
}
// 抽离成一个单独的组件
class MyApp extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
                // 导航条
                appBar:AppBar(title:Text('Flutter App')),
                // 主体
                body:HomeContent(),
            ),
            // 主题
            theme: ThemeData(primarySwatch:Colors.yellow),
        );
    }
}

// 布局实例
class HomeContent extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return Column(
            children: <Widget>[
                Row(
                    children: <Widget>[
                        Expanded(
                            child:Container(
                                height:180,
                                color:Colors.black,
                                child: Text('你好,Flutter'),
                            ),
                        )
                    ],
                ),
                SizedBox(height:10),
                Row(
                    children: <Widget>[
                        Expanded(
                            flex: 2,
                            child:Container(
                                height:180,
                                child:Image.network("http://www.itying.com/images/flutter/1.png",fit:BoxFit.cover)
                            ) 
                        ),
                        SizedBox(width:10),
                        Expanded(
                            flex:1,
                            child:Container(
                                height:180,
                                child:ListView(
                                    children: <Widget>[
                                        Container(
                                            height:85,
                                            child:Image.network("http://www.itying.com/images/flutter/1.png",fit:BoxFit.cover)
                                        ),
                                        SizedBox(height:10),
                                        Container(
                                            height:85,
                                            child:Image.network("http://www.itying.com/images/flutter/2.png",fit:BoxFit.cover)
                                        )
                                    ], 
                                )
                            )
                        )
                    ],
                )
            ],
        );
    }
}

0 人点赞