第二篇、认识Flutter常用组件

103 阅读4分钟

1、Container

Container 用来创建一个可见的矩形元素,相当于 HTML 中的 div 元素。

- Container 的定义:

Container({
    Key key,
    // 容器子Widget对齐方式
    this.alignment,
    // 容器内部padding
    this.padding,
    // 背景色
    Color color,
    // 背景装饰
    Decoration decoration,
    // 前景装饰
    this.foregroundDecoration,
    // 容器的宽度
    double width,
    // 容器的高度
    double height,
    // 容器大小的限制条件
    BoxConstraints constraints,
    // 容器外部margin
    this.margin,
    // 变换,如旋转
    this.transform,
    // 容器内子Widget
    this.child,
  })

- BoxDecoration 装饰

const BoxDecoration({
  // 背景色
  this.color,
  // 背景图片
  this.image,
  // 边框样式
  this.border,
  // 边框圆角
  this.borderRadius,
  // 阴影
  this.boxShadow,
  // 渐变
  this.gradient,
  // 背景混合模式
  this.backgroundBlendMode,
  // 形状
  this.shape = BoxShape.rectangle,
})

示例

Container(
  alignment: Alignment.center,	//child的对齐方式
  height: 44,
  width: double.infinity,	// 无限制
  color: Colors.red / Color(0xFF36373f),	// 背景颜色,会被decoration中配置color效果覆盖
  padding: EdgeInsets.fromLTRB(left, top, right, bottom),
  margin: EdgeInsets.all(20); // margin也可以使用EdgeInsets.fromLTRB
  constraints: BoxConstraints(	// 容器的尺寸约束,可以使用BoxConstraints类来设置最小和最大宽度、高度等
    maxHeight: 48,
    minHeight: 48
    ......
  ),
  decoration: BoxDecoration(	 // 容器的装饰效果,例如边框、阴影等
	border: Border.all(
	  color: Colors.green, 	// 边框颜色
	  width: 1, 	// 边框宽度  
	),
    borderRadius: BorderRadius.circular(16),      
  ),
  child: Text('Hello world!'),	// container中的内容widget
)

-自定义HEX颜色

Colors.red 可以换成 Color(0xFFcc0003), 其中0xFF是固定的,cc0003是HEX颜色值

-自定义圆角

borderRadius: BorderRadius.only(
  topLeft: Radius.circular(0),
  topRight: Radius.circular(0),
  bottomLeft: Radius.circular(12),
  bottomRight: Radius.circular(12),
)

-拱形圆角

borderRadius: const BorderRadius.vertical(
  top: Radius.elliptical(120, 40), // 横向椭圆半径120,纵向半径40
),

2、Row / Column

Row 将 children 排成一行,Column 将 children 排成一列,其中个各项属性的使用类似 CSS 中的Flex 布局

常用属性:

Row(
  mainAxisAlignment: MainAxisAlignment.start, //children在主轴上的对齐方式,默认为start。还可以设置为 center、end、spaceBetween(children之间的空白区域相等,首尾child都靠近首尾,没有间隙)
  crossAxisAlignment: CrossAxisAlignment.start, // children在交叉轴的对齐方式,Row默认为start,Column默认为center
  verticalDirection: VerticalDirection.down,	// children在垂直方向的排列顺序,默认down为从上到下,还可以设置从下到上排列的up
  children: [
	Text('left'),		// 还可以使用Expanded对子节点进行权重处理
	Text('center'),
	Text('right'),
  ]
)

3、Text

Text 创建带样式的文本。

常用属性:

Text(
  'Hello, World!',
  textAlign: TextAlign.center,	// 文本在水平方向的对齐方式:left、center、right、justify(两端对齐)
  style: TextStyle(
  	color: Color(0xFF95A3A9),
	fontSize: 14,
	fontWeight: FontWeight.w400, // 默认为w400/normal。加粗:w700/bold
	height: 1.4,	// 行间距,字体的1.4倍
  ),
  maxLines: 3,		// 指定文本最大行数,超出部分省略
  overflow: TextOverflow.ellipsis,	// 使用省略号来表示被截断的文本
)

4、Icon

Icon 用于显示矢量图标,支持 内置图标iconfont 图标。衍生的组件有 ImageIcon、IconButton 等。

Icon(
  Icons.favorite,
  color: Colors.red,
  size: 24,
),

ImageIcon(AssetImage("images/icon_home.png")),

IconButton(
  icon: Image.asset('images/icon_home.png'),
  onPressed: () {
    ToastUtil.showToast('保存');
}),

5、Image

Image 用于显示图像,可以加载网络图片或本地资源图片。

加载资源图片需要先将图片资源放入项目中。例如:新建images文件夹,将图片放在该文件夹下,然后在 pubspec.yaml 中配置 assets。

// pubspec.yaml
assets:
  - assets/images/   // 引入目录下的所有文件(包括子目录)作为资源引入
  - assets/images/icon_avatar.png  // 引入单个文件资源

// 静态函数
Image.asset(
  "assets/images/icon_home.png",
  width: 16,
  height: 16,
  fit: BoxFit.cover,	// 图片的缩放形式,将图片等比例缩放填满容器,可能会发生剪切
);

Image.network(image_url);

// 底部导航栏使用
BottomNavigationBarItem(
  icon: Image.asset(
    'assets/images/icon_home.png',
    width: 24,

  ),
  activeIcon: Image.asset(
    'assets/images/icon_home_active.png',
    width: 24,

  ),
  label: '首页',
),

6、按钮 Button

Flutter 中的 Button 组件有很多,常用的有:ElevatedButtonIconButtonTextButtonButtonBar(按钮组)FloatingActionButton(浮动按钮)

 const ElevatedButton({
    Key? key,
    // 点击事件
    required VoidCallback? onPressed,
    // 长按
    VoidCallback? onLongPress,
    // hover
    ValueChanged<bool>? onHover,
    ValueChanged<bool>? onFocusChange,

    // 样式
    ButtonStyle? style,

    // 焦点
    FocusNode? focusNode,
    bool autofocus = false,
    Clip clipBehavior = Clip.none,

    // 按钮内容
    required Widget? child,
  })
  • ButtonStyle 样式定义
class ButtonStyle with Diagnosticable {
  /// Create a [ButtonStyle].
  const ButtonStyle({
    // 文字
    this.textStyle,
    // 背景色
    this.backgroundColor,
    // 前景色
    this.foregroundColor,
    // 鼠标滑过颜色
    this.overlayColor,
    // 阴影
    this.shadowColor,
    // 阴影高度
    this.elevation,
    // 内边距
    this.padding,
    // 最小尺寸
    this.minimumSize,
		// 固定 size
    this.fixedSize,
    // 最大最小尺寸
    this.maximumSize,
    // 边框
    this.side,
    // 形状
    this.shape,
    // 鼠标光标
    this.mouseCursor,
    // 紧凑程度
    this.visualDensity,
    // 配置可以按下按钮的区域的尺寸
    this.tapTargetSize,
    // 定义 [shape] 和 [elevation] 的动画更改的持续时间
    this.animationDuration,
    // 检测到的手势是否应该提供声音和/或触觉反馈
    this.enableFeedback,
    // 子元素对齐方式
    this.alignment,
    // 墨水效果
    this.splashFactory,
  });

示例

import 'package:flutter/material.dart';

class ButtonPage extends StatelessWidget {
  const ButtonPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // ElevatedButton
            ElevatedButton(
              onPressed: () {},
              child: const Text('ElevatedButton'),
              style: ButtonStyle(
                // 背景色
                backgroundColor: MaterialStateProperty.all(Colors.yellow),
                // 前景色
                foregroundColor: MaterialStateProperty.all(Colors.red),
                // 鼠标滑过颜色
                overlayColor: MaterialStateProperty.all(Colors.blue),
                // 阴影颜色
                shadowColor: MaterialStateProperty.all(Colors.red),
                // 阴影高度
                elevation: MaterialStateProperty.all(8),
                // 边框
                side: MaterialStateProperty.all(const BorderSide(
                  width: 5,
                  color: Colors.cyan,
                )),
                // 固定尺寸
                fixedSize: MaterialStateProperty.all(const Size(200, 100)),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

输出

image.png

其它按钮

  • TextButton 文字按钮
  • OutlinedButton 边框按钮
  • IconButton 图标按钮
  • FloatingActionButton 浮动按钮
  • InkWell + Container 完全自定义样式
import 'package:flutter/material.dart';

class ButtonPage extends StatelessWidget {
  const ButtonPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 文字按钮
            TextButton(
              onPressed: () {},
              child: const Text('TextButton'),
            ),

            // 边框按钮
            OutlinedButton(
              onPressed: () {},
              child: const Text('OutlinedButton'),
            ),

            // 图标按钮
            IconButton(
              onPressed: () {},
              icon: const Icon(
                Icons.holiday_village,
              ),
              iconSize: 50,
              color: Colors.amber,
            ),

            // 带图标 TextButton
            TextButton.icon(
              onPressed: () {},
              icon: const Icon(Icons.holiday_village),
              label: const Text('带图标 TextButton'),
            ),

            // 带图标 OutlinedButton
            OutlinedButton.icon(
              onPressed: () {},
              icon: const Icon(Icons.holiday_village),
              label: const Text('带图标 OutlinedButton'),
            ),
            // 圆形悬浮按钮
            FloatingActionButton(
              onPressed: () {
              print('FloatingActionButton pressed');
            },
             child: Icon(Icons.add),
            ),
            // 带水波纹效果的自定义按钮
            InkWell(
              onTap: () {
                print('InkWell Button pressed');
            },
             child: Container(
            padding: EdgeInsets.all(12),
            decoration: BoxDecoration(
            color: Colors.blue,
            borderRadius: BorderRadius.circular(8)),
                child: Text('InkWell Button', style: TextStyle(color: Colors.white)),
            ),
        )
            
          ],
        ),
      ),
    );
  }
}

注意:  TextButton.icon OutlinedButton.icon 可以输出带图标文字的按钮

输出

image.png