Flutter - UI布局

一、容器Widget

1. Scaffold

Scaffold 作为页面的脚手架,基础区域包含顶部导航栏 appBar、主体内容区 body、侧边抽屉 drawer、悬浮按钮 floatingActionButton、底部导航栏 bottomNavigationBar。

Dart 复制代码
Scaffold(
  appBar: AppBar( // 顶部导航栏
    title: Text('首页'),
  ),
  body: Center( // 主体
    child: Text('页面内容'),
  ),
  drawer: Drawer( // 侧边栏
    child: ListView(children: [ListTile(title: Text('设置'))]),
  ),
  floatingActionButton: FloatingActionButton( // 悬浮按钮
    child: Icon(Icons.add),
    tooltip: '悬浮按钮',
    onPressed: () {}, 
  ),
  bottomNavigationBar:  BottomNavigationBar( // 底部导航栏
    items: [BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页')],
    onTap: (index) {},
  ),
)

2. Container

Container 是一个多功能容器,它通过组合多种基础功能(尺寸控制、边距、装饰、对齐等)简化复杂 UI 的实现。

Dart 复制代码
Container(
  width: 160, height: 40, // 宽高
  padding:  EdgeInsets.symmetric(horizontal: 6), // 内边距
  alignment: Alignment.topLeft, // 顶部|左侧对齐
  color: Colors.white, // 背景色(与 decoration互斥)
  decoration: BoxDecoration( // 装饰组合(背景色、圆角、阴影等)
    color: Colors.black12,
    borderRadius: BorderRadius.circular(6),
  ),
  child: Text("容器") // 子组件
)

二、布局Widget

1. Row

Row 用于水平排列子组件,通过主轴(水平方向)和交叉轴(垂直方向)控制子组件的排列方式。

Dart 复制代码
Row(
  mainAxisAlignment: MainAxisAlignment.center, // 水平居中(默认值:start)
  crossAxisAlignment: CrossAxisAlignment.start, // 顶部对齐(默认值:center)
  textDirection: TextDirection.ltr, // 从左到右
  spacing: 6, // 间距
  children: [ // 子组件
    Expanded(flex: 1, child: Container(color: Colors.gray)), // 占1/3空间
    Expanded(flex: 2, child: Container(color: Colors.blue)), // 占2/3空间
  ]
)

2. Column

Column 用于垂直排列子组件,通过主轴(垂直方向)和交叉轴(水平方向)控制子组件的排列方式。

Dart 复制代码
Column(
  mainAxisAlignment: MainAxisAlignment.center, // 垂直居中(默认值:start)
  crossAxisAlignment: CrossAxisAlignment.start, // 左侧对齐(默认值:center)
  verticalDirection: VerticalDirection.down, // 从上到下
  spacing: 6, // 间隔
  children: [ // 子组件
    Expanded(flex: 2, child: Container(color: Colors.gray)), // 占2/3空间
    Expanded(flex: 1, child: Container(color: Colors.blue)), // 占1/3空间
  ]
)

3. Stack

Stack 用于实现​​层叠布局​​,允许子组件按绘制顺序(从底部到顶部)堆叠在一起。

Dart 复制代码
Stack(
  alignment: AlignmentDirectional.bottomStart, // 底部|左侧对齐(默认值:topStart)
  textDirection: TextDirection.ltr, // 从左到右
  children: [
    Container(height: 44, color: Colors.blue), // 设置高度、背景色
    Positioned(top: 10, left: 10, width: 20, height: 20, child: Icon(Icons.star)), // 定位组件
    Positioned.fill(child: Container(color: Color(0x33000000))), // 半透明遮罩
  ],
)

4. Flex

Flex 用于创建​​弹性布局​​的核心组件,它通过主轴(main axis)和交叉轴(cross axis)控制子组件的排列方式。

Dart 复制代码
Flex(
  direction: Axis.horizontal, // 水平方向
  spacing: 20, // 间距
  children: [ 
    Flexible(flex: 1, child: Container(color: Colors.grey)), // 填充剩余空间
    Expanded(flex: 2, child: Container(color: Colors.red)), // 强制填满剩余空间
  ],
)

5. SizedBox

SizedBox 用于​​精确控制尺寸​​,它既能约束子组件尺寸,也能作为空白占位符使用。

Dart 复制代码
SizedBox(
  width: 180, height: 40, // 宽高
  child: Center(
    child: Text('精准宽高'),
  ),
)

Row(
  children: [
    SizedBox(width: 20), // 空白占位符
    Text('水平排列'),
  ],
)

6. Align

Align 用于​​控制子组件在父容器中的位置。

Dart 复制代码
Align(
  Alignment: Alignment.topLeft,
  child: Text('左侧|顶部对齐'),
)

7. Center

Center 用于控制子组件的水平|垂直居中。

Dart 复制代码
Center(
  child: Text('水平|垂直居中'),
)

8. Padding

Padding 用于​​控制子组件内边距​​,通过在子组件周围添加空白区域来调整布局间距。

Dart 复制代码
Padding(
  padding: EdgeInsets.all(8), 
  child: Text('带内边距的文本'),
)

三、滚动Widget

1. SingleChildScrollView

SingleChildScrollView 用于​​包裹单个子组件​​的滚动容器,支持垂直或水平方向的滚动。

Dart 复制代码
SingleChildScrollView(
  scrollDirection: Axis.vertical, // 纵向滚动
  physics: BouncingScrollPhysics(), // 边界回弹
  child: Container(height: 1000),
)

2. ListView

ListView 用于创建​​可滚动列表​​的核心组件,它可以高效地显示线性排列的数据项,支持垂直或水平滚动。

Dart 复制代码
ListView( // 静态列表
  padding: EdgeInsets.symmetric(vertical: 10),
  children: [
    ListTile(title: Text('List')),
    Container(
      height: 50,
      alignment: Alignment.centerLeft,
      padding: EdgeInsets.symmetric(horizontal: 20),
      child: Text('Row 1'),
    ),
  ],
)
Dart 复制代码
ListView.builder( // 动态列表
  itemCount: 20,
  itemBuilder: (context, index) {
    return Container(
      height: 50,
      alignment: Alignment.centerLeft,
      padding: EdgeInsets.symmetric(horizontal: 20),
      child: Text('Row ${index+1}'),
    );
  },
)
Dart 复制代码
ListView.separated( // 动态列表(设置分隔线)
  itemCount: 20,
  separatorBuilder: (context, index) => Divider(height: 1),
  itemBuilder: (context, index) {
    return Container(
      height: 50,
      alignment: Alignment.centerLeft,
      padding: EdgeInsets.symmetric(horizontal: 20),
      child: Text('Row ${index+1}'),
    );
  },
)

3. GridView

GridView 用于创建​​网格布局​​,它可以在二维空间中排列子组件,支持垂直或水平滚动。

Dart 复制代码
GridView( // 静态网格
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3, // 每行3列
    crossAxisSpacing: 10, // 列间距
    mainAxisSpacing: 10, // 行间距
    childAspectRatio: 0.7 // 宽高比
  ),
  children: [
    Image.asset('images/image_1.png'),
    Image.asset('images/image_2.png'),
    ...
  ],
)
Dart 复制代码
GridView.count( // 静态网格
  crossAxisCount: 3, // 每行3列
  crossAxisSpacing: 10, // 列间距
  mainAxisSpacing: 10, // 行间距
  childAspectRatio: 0.7 // 宽高比
  children: [
    Image.asset('images/image_1.png'),
    Image.asset('images/image_2.png'),
    ...
  ],
)
Dart 复制代码
GridView.builder( // 动态网格
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3, // 每行3列
    crossAxisSpacing: 10, // 列间距
    mainAxisSpacing: 10, // 行间距
    childAspectRatio: 0.7 // 宽高比
  ),
  itemBuilder: (BuildContext context, int index) {
    return Image.asset('images/image_${index+1}.png');
  }
)

四、内容Widget

1. Text

Text 用于文本内容的​​显示​​,提供了丰富的文本样式控制能力。

Dart 复制代码
Text('文本内容',
  style: TextStyle(color: Color(0xFF333333), fontSize: 18), // 文本样式
  textAlign: TextAlign.left, // 文本对齐方式
  overflow: TextOverflow.ellipsis, // 溢出处理方式
  maxLines: 3, // 最高行数
)

2. TextField

TextField 用于​​文本输入​​,它提供了强大的文本输入、编辑和验证功能。

Dart 复制代码
final controller = TextEditingController();
final focusNode = FocusNode();

TextField(
  controller: this.controller, // 文本编辑
  focusNode: this.focusNode, // 焦点节点
  decoration: InputDecoration( // 内容装饰
    hintText: '请输入密码',
    hintStyle: TextStyle(fontSize: 16, color: Colors.black12),
  ),
  style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
  keyboardType: TextInputType.visiblePassword, // 键盘类型
  textInputAction: TextInputAction.done, // 完成按钮
  obscureText: true, // 是否隐藏内容
  onChanged: (value) => print('文本变化-$value'),
  onEditingComplete: () => print('编辑完成'),
  onSubmitted: (value) {
    this.focusNode.unfocus(); // 隐藏键盘
  },
)

void changeText() {
  this.controller.text = '123456'; // 文本赋值
}

3. Image

Image 用于​​图片内容的展示​,支持从多种来源加载图片(本地资源、网络、内存字节等)。

3.1 在工程的 pubspec.yaml 中配置 assets 路劲。

3.2 用 Image.asset 展示内置 images 图片。

Dart 复制代码
Image.asset('images/logo.png',
  width: 120, 
  height: 40,
  fit: BoxFit.fill, // 拉伸填充
)

3.2 用 Image.network 展示网络 URL 图片。

Dart 复制代码
Image.network('http://gips2.baidu.com/it/u=195724436,3554684702&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960',
  width: 300,
  height: 100,
  fit: BoxFit.cover, // 比例填充
 )

五、手势Widget

1. GestureDetector

GestureDetector 用于添加各种手势事件,包含点击、长按、拖拽、缩放等手势操作。

Dart 复制代码
GestureDetector(
  onTap: () => print('单击'),
  onDoubleTap: () => print('双击'),
  onLongPress: () => print('长按'),
  child: Padding(
    padding: EdgeInsets.symmetric(horizontal: 30, vertical: 15),
    child: Text('手势交互'),
  ),
)

2. InkWell

InkWell 用于​​添加触摸事件​​,它提供了单击、长按等交互的视觉反馈,实现墨水涟漪效果必须包裹在 Material 组件内。

Dart 复制代码
 Material( // 添加Material层
  child: InkWell(
    onTap: () => print('单击'),
    onDoubleTap: () => print('双击'),
    onLongPress: () => print('长按'),
    splashColor: Color(0x22333333), // 飞溅颜色
    highlightColor: Color(0x44333333), // 高亮颜色
    child: Padding(
      padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
      child: Text('点击 - ​​墨水涟漪效果'),
    ),
  ),
)

六、按钮Widget

1. ElevatedButton

ElevatedButton 是​​凸起按钮,适用于主要操作、表单提交。

Dart 复制代码
ElevatedButton(
  onPressed: () => print('点击'),
  child: Text('凸起按钮', style: TextStyle(fontSize: 20, color: Colors.white)),
  style: ElevatedButton.styleFrom(
    backgroundColor: Color(0xFF52d0c2), // 背景色
    elevation: 3, // 阴影高度
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(20), // 圆角
    ),
    padding: EdgeInsets.symmetric(horizontal: 30, vertical: 15), // 内边距
  ),
)

2. TextButton

TextButton 是​​扁平化文本按钮​​,适用于次要操作、对话框选项和链接式操作。

Dart 复制代码
TextButton(
  onPressed: () => print('点击'),
  child: Text('文本按钮', style: TextStyle(fontSize: 20, color: Colors.white)),
  style: TextButton.styleFrom(
    backgroundColor: Colors.black, // 背景色
    padding: EdgeInsets.symmetric(horizontal: 30, vertical: 15), // 内边距
  ),
)

3. FilledButton

FilledButton 是​​实心填充背景​​的按钮,介于 ElevatedButton 和 TextButton 之间。

Dart 复制代码
FilledButton(
  onPressed: () => print('点击'),
  child: Text('填充按钮', style: TextStyle(fontSize: 20, color: Colors.white)),
  style: FilledButton.styleFrom(
    elevation: 3, // 阴影高度
    backgroundColor: Colors.black, // 背景色
    padding: EdgeInsets.symmetric(horizontal: 30, vertical: 15), // 内边距
  ),
)

4. OutlinedButton

OutlinedButton 是带边框按钮​​,通过边框强调按钮形状,同时保持背景透明。

Dart 复制代码
OutlinedButton(
  onPressed: () => print('点击'),
  child: Text('带边框按钮', style: TextStyle(fontSize: 20, color: Colors.black)),
  style: OutlinedButton.styleFrom(
    side: BorderSide(width: 1, color: Colors.black), // 边框属性
    backgroundColor: Colors.white, // 背景色
    padding: EdgeInsets.symmetric(horizontal: 30, vertical: 15), // 内边距
  ),
),
Dart 复制代码
OutlinedButton(
  onPressed: () => print('点击'),
  child: SizedBox(
    width: 196,
    child: Row(
      mainAxisAlignment: MainAxisAlignment.center,
      spacing: 10,
      children: [
        Icon(Icons.camera) , 
        Text('带边框的图文按钮', style: TextStyle(fontSize: 18))
      ],
    ),
  ),
  style: OutlinedButton.styleFrom(
    side: BorderSide(width: 1, color: Colors.black),
    backgroundColor: Colors.white, // 背景色
    padding: EdgeInsets.symmetric(horizontal: 10, vertical: 15), // 内边距
  ),
)

七、显隐Widget

1. Visibility

​Visibility​​ 用于​​动态控制子组件显隐​​,同时支持保留布局空间或状态。

Dart 复制代码
Visibility(
  visible: true, // 显示
  maintainState: true, // 保留状态
  child: Text('显示文本')
)

2. Offstage

Offstage 用于​​控制子组件显隐​​,默认保留状态,隐藏时不占空间。

Dart 复制代码
Offstage(
  offstage: true, // 隐藏
  child: Text('隐藏文本'),
)

3. Opacity

Opacity 用于​​修改子组件透明度。

Dart 复制代码
Opacity(
  opacity: 0.5, // 半透明
  child: Text('半透明字体'),
)

4. AnimatedOpacity

AnimatedOpacity 用于实现​​透明度渐变动画。

Dart 复制代码
double opacity = 0.5;

GestureDetector(
  onTap: () => {
    setState(() { // 状态变量
      this.opacity = 1;
    });
  },
  child: AnimatedOpacity(
    opacity: this.opacity, // 透明度
    duration: Duration(milliseconds: 500), // 500毫秒
    onEnd: () => print('动画结束'),
    child: Text('渐变文本'),
  ),
)

5. if / for

通过 if / for 语句控制 Widget 是否渲染。

Dart 复制代码
Column(
  children: [
    if (_isLoading) // if语句
      Text('加载中'),
    _isLoading ? Text('加载中') : Text('加载完成'), // 三元运算符
  ],
)
Dart 复制代码
Column(
  children: [
    for (int i=1; i<=5; i++) // for循环
      Text('Item $i'),
  ],
)