第4课:布局与样式
第4课:布局与样式
🎯 学习目标
- 深入理解Flutter的布局系统原理
- 掌握高级布局组件的使用方法
- 学会创建响应式用户界面
- 理解主题和样式的管理机制
- 能够设计美观的UI界面
📋 课程内容
4.1 Flutter布局系统深入
4.1.1 布局原理
Flutter的布局系统基于约束(Constraints)和尺寸(Size):
- 约束:父Widget给子Widget的尺寸限制
- 尺寸:子Widget根据约束确定的实际尺寸
- 位置:子Widget在父Widget中的位置
布局流程:
1. 父Widget传递约束给子Widget
2. 子Widget根据约束确定自己的尺寸
3. 父Widget根据子Widget的尺寸确定位置
4. 递归处理所有子Widget
4.1.2 约束类型
// 约束示例
class ConstraintExample extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('约束示例')),body: Column(children: [// 无约束 - 子Widget决定尺寸Container(color: Colors.blue[100],child: Text('无约束文本'),),SizedBox(height: 20),// 宽松约束 - 子Widget可以任意尺寸Container(color: Colors.green[100],child: Center(child: Text('宽松约束文本'),),),SizedBox(height: 20),// 严格约束 - 子Widget必须填满Container(width: double.infinity,height: 100,color: Colors.orange[100],child: Center(child: Text('严格约束文本'),),),],),);}
}
4.2 高级布局组件
4.2.1 Expanded和Flexible
class ExpandedExample extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Expanded和Flexible示例')),body: Column(children: [// 使用ExpandedRow(children: [Expanded(flex: 2, // 占据2份空间child: Container(height: 80,color: Colors.red,child: Center(child: Text('Expanded 2', style: TextStyle(color: Colors.white))),),),Expanded(flex: 1, // 占据1份空间child: Container(height: 80,color: Colors.blue,child: Center(child: Text('Expanded 1', style: TextStyle(color: Colors.white))),),),Expanded(flex: 1, // 占据1份空间child: Container(height: 80,color: Colors.green,child: Center(child: Text('Expanded 1', style: TextStyle(color: Colors.white))),),),],),SizedBox(height: 20),// 使用FlexibleRow(children: [Flexible(flex: 2,child: Container(height: 80,color: Colors.purple,child: Center(child: Text('Flexible 2', style: TextStyle(color: Colors.white))),),),Flexible(flex: 1,child: Container(height: 80,color: Colors.teal,child: Center(child: Text('Flexible 1', style: TextStyle(color: Colors.white))),),),// 固定尺寸Container(width: 100,height: 80,color: Colors.amber,child: Center(child: Text('固定尺寸', style: TextStyle(color: Colors.black))),),],),],),);}
}
4.2.2 Wrap组件
class WrapExample extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Wrap组件示例')),body: Padding(padding: EdgeInsets.all(16.0),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text('标签云示例:', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),SizedBox(height: 16),// 基本WrapWrap(spacing: 8.0, // 水平间距runSpacing: 8.0, // 垂直间距children: [_buildTag('Flutter', Colors.blue),_buildTag('Dart', Colors.green),_buildTag('Mobile', Colors.orange),_buildTag('Development', Colors.purple),_buildTag('UI', Colors.red),_buildTag('Cross-platform', Colors.teal),_buildTag('Google', Colors.indigo),_buildTag('Open Source', Colors.pink),],),SizedBox(height: 30),Text('按钮组示例:', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),SizedBox(height: 16),// 按钮WrapWrap(spacing: 12.0,runSpacing: 12.0,children: [ElevatedButton(onPressed: () => print('按钮1'),child: Text('按钮1'),style: ElevatedButton.styleFrom(primary: Colors.blue,onPrimary: Colors.white,),),ElevatedButton(onPressed: () => print('按钮2'),child: Text('按钮2'),style: ElevatedButton.styleFrom(primary: Colors.green,onPrimary: Colors.white,),),ElevatedButton(onPressed: () => print('按钮3'),child: Text('按钮3'),style: ElevatedButton.styleFrom(primary: Colors.orange,onPrimary: Colors.white,),),ElevatedButton(onPressed: () => print('按钮4'),child: Text('按钮4'),style: ElevatedButton.styleFrom(primary: Colors.purple,onPrimary: Colors.white,),),ElevatedButton(onPressed: () => print('按钮5'),child: Text('按钮5'),style: ElevatedButton.styleFrom(primary: Colors.red,onPrimary: Colors.white,),),],),],),),);}Widget _buildTag(String text, Color color) {return Container(padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),decoration: BoxDecoration(color: color.withOpacity(0.1),borderRadius: BorderRadius.circular(20),border: Border.all(color: color),),child: Text(text,style: TextStyle(color: color,fontSize: 14,fontWeight: FontWeight.w500,<