当前位置: 首页 > news >正文

Flutter之Widget体系与布局原理

第3章:Widget体系与布局原理

3.1 Widget树的构建与渲染机制

3.1.1 Flutter渲染流水线解析

Flutter的渲染系统是其高性能的核心所在。理解渲染机制对于优化应用性能至关重要。

// Flutter渲染流水线的三棵树结构示例
class RenderingPipelineDemo extends StatelessWidget {@overrideWidget build(BuildContext context) {// Widget Tree - 配置信息return Scaffold(appBar: AppBar(title: Text('渲染流水线演示')),body: Container(  // Widget节点padding: EdgeInsets.all(16.0),child: Column(children: [Text('Hello Flutter'),  // Widget节点ElevatedButton(onPressed: () {},child: Text('点击按钮'),),],),),);}
}// Element Tree对应的概念示例
/*
Widget Tree          Element Tree            RenderObject Tree
-----------         --------------          -------------------
Scaffold       →    ScaffoldElement    →    RenderScaffold
├─AppBar       →    ├─AppBarElement    →    ├─RenderAppBar
└─Container    →    └─ContainerElement →    └─RenderContainer└─Column     →      └─ColumnElement  →      └─RenderFlex├─Text     →        ├─TextElement   →        ├─RenderParagraph└─Button   →        └─ButtonElement →        └─RenderButton
*/

3.1.2 Widget树的构建过程

// 演示Widget树构建的详细过程
class WidgetTreeBuildDemo extends StatefulWidget {@override_WidgetTreeBuildDemoState createState() => _WidgetTreeBuildDemoState();
}class _WidgetTreeBuildDemoState extends State<WidgetTreeBuildDemo> {int _counter = 0;@overrideWidget build(BuildContext context) {print('🔄 build方法被调用 - counter: $_counter');return Scaffold(appBar: AppBar(title: Text('Widget树构建演示'),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [// 每次build都会创建新的Text WidgetText('计数器值:$_counter',style: Theme.of(context).textTheme.headlineMedium,),SizedBox(height: 20),// 但Element树和RenderObject树会被复用ElevatedButton(onPressed: _incrementCounter,child: Text('增加计数'),),],),),);}void _incrementCounter() {setState(() {_counter++;// setState触发Widget树重建,但Element树只会更新必要部分});}@overridevoid dispose() {print('🗑️ Widget被销毁');super.dispose();}
}

3.1.3 渲染性能优化原理

// 性能优化的最佳实践
class PerformanceOptimizedWidget extends StatefulWidget {@override_PerformanceOptimizedWidgetState createState() => _PerformanceOptimizedWidgetState();
}class _PerformanceOptimizedWidgetState extends State<PerformanceOptimizedWidget> {int _counter = 0;@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('性能优化演示')),body: Column(children: [// ❌ 错误做法:每次build都创建新的expensive widget// ExpensiveWidget(),// ✅ 正确做法1:提取为常量const ExpensiveStaticWidget(),// ✅ 正确做法2:使用const构造函数const Padding(padding: EdgeInsets.all(16.0),child: Text('这是一个常量Widget'),),// ✅ 正确做法3:条件性重建CounterDisplay(counter: _counter),// ✅ 正确做法4:使用Builder减少重建范围Builder(builder: (context) => ElevatedButton(onPressed: () => setState(() => _counter++),child: Text('增加计数'),),),],),);}
}// 独立的计数器显示组件,只有当counter改变时才重建
class CounterDisplay extends StatelessWidget {final int counter;const CounterDisplay({Key? key, required this.counter}) : super(key: key);@overrideWidget build(BuildContext context) {print('🔄 CounterDisplay重建 - counter: $counter');return Container(padding: EdgeInsets.all(16),decoration: BoxDecoration(color: Colors.blue[100],borderRadius: BorderRadius.circular(8),),child: Text('当前计数:$counter',style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),),);}
}// 昂贵的静态Widget - 使用const避免重建
class ExpensiveStaticWidget extends StatelessWidget {const ExpensiveStaticWidget({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {print('💰 ExpensiveStaticWidget被构建(应该只出现一次)');return Container(height: 200,child: ListView.builder(itemCount: 100,itemBuilder: (context, index) => ListTile(title: Text('静态项目 $index'),),),);}
}

3.2 StatelessWidget与StatefulWidget详解

3.2.1 StatelessWidget深入理解

// StatelessWidget的完整实现示例
class CustomStatelessWidget extends StatelessWidget {final String title;final Color backgroundColor;final VoidCallback? onTap;// 构造函数 - 所有属性都应该是finalconst CustomStatelessWidget({Key? key,required this.title,this.backgroundColor = Colors.blue,this.onTap,}) : super(key: key);@overrideWidget build(BuildContext context) {// build方法是纯函数,相同输入总是产生相同输出return GestureDetector(onTap: onTap,child: Container(padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),decoration: BoxDecoration(color: backgroundColor,borderRadius: BorderRadius.circular(8),boxShadow: [BoxShadow(color: Colors.black26,blurRadius: 4,offset: Offset(0, 2),),],),child: Text(title,style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,),),),);}// 重写操作符以支持比较@overridebool operator ==(Object other) =>identical(this, other) ||other is CustomStatelessWidget &&runtimeType == other.runtimeType &&title == other.title &&backgroundColor == other.backgroundColor;@overrideint get hashCode => title.hashCode ^ backgroundColor.hashCode;
}// StatelessWidget的最佳实践示例
class UserProfileCard extends StatelessWidget {final User user;final VoidCallback? onEdit;const UserProfileCard({Key? key,required this.user,this.onEdit,}) : super(key: key);@overrideWidget build(BuildContext context) {return Card(margin: EdgeInsets.all(8),child: Padding(padding: EdgeInsets.all(16),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [// 用户头像和基本信息Row(children: [CircleAvatar(radius: 30,backgroundImage: NetworkImage(user.avatarUrl),),SizedBox(width: 16),Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text(user.name,style: Theme.of(context).textTheme.headlineSmall,),Text(user.email,style: Theme.of(context).textTheme.bodyMedium,),],),),if (onEdit != null)IconButton(icon: Icon(Icons.edit),onPressed: onEdit,),],),SizedBox(height: 12),// 用户描述if (user.bio.isNotEmpty)Text(user.bio,style: Theme.of(context).textTheme.bodySmall,),],),),);}
}// User模型类
class User {final String name;final String email;final String avatarUrl;final String bio;const User({required this.name,required this.email,required this.avatarUrl,this.bio = '',});
}

3.2.2 StatefulWidget完整生命周期

// StatefulWidget完整生命周期演示
class LifecycleDemo extends StatefulWidget {final String title;const LifecycleDemo({Key? key, required this.title}) : super(key: key);@override_LifecycleDemoState createState() {print('📱 1. createState() - 创建State对象');return _LifecycleDemoState();}
}class _LifecycleDemoState extends State<LifecycleDemo>with WidgetsBindingObserver {int _counter = 0;late String _title;// 2. 构造函数_LifecycleDemoState() {print('🏗️ 2. State构造函数');}// 3. initState - 只调用一次@overridevoid initState() {super.initState();print('🎬 3. initState() - 初始化状态');_title = widget.title;// 添加生命周期观察者WidgetsBinding.instance.addObserver(this);// 异步初始化_asyncInit();}Future<void> _asyncInit() async {// 模拟异步数据加载await Future.delayed(Duration(seconds: 1));if (mounted) {  // 检查Widget是否还存在setState(() {_counter = 10;});}}// 4. didChangeDependencies - 依赖变化时调用@overridevoid didChangeDependencies() {super.didChangeDependencies();print('🔄 4. didChangeDependencies() - 依赖改变');}// 5. build - 构建UI@overrideWidget build(BuildContext context) {print('🎨 5. build() - 构建UI, counter: $_counter');return Scaffold(appBar: AppBar(title: Text(_title),actions: [IconButton(icon: Icon(Icons.refresh),onPressed: _refresh,),],),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text('生命周期演示',style: Theme.of(context).textTheme.headlineMedium,),SizedBox(height: 20),Text('计数器:$_counter',style: Theme.of(context).textTheme.headlineSmall,),SizedBox(height: 20),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [ElevatedButton(onPressed: _increment,child: Text('增加'),),ElevatedButton(onPressed: _decrement,child: Text('减少'),),],),],),),);}// 6. didUpdateWidget - Widget配置改变时调用@overridevoid didUpdateWidget(LifecycleDemo oldWidget) {super.didUpdateWidget(oldWidget);print('🔃 6. didUpdateWidget() - Widget更新');if (oldWidget.title != widget.title) {setState(() {_title = widget.title;});}}// 7. setState - 状态改变时调用void _increment() {setState(() {print('📈 setState() - 增加计数器');_counter++;});}void _decrement() {setState(() {print('📉 setState() - 减少计数器');_counter--;});}void _refresh() {setState(() {print('🔄 setState() - 刷新状态');_counter = 0;});}// 8. deactivate - Widget被移除时调用@overridevoid deactivate() {print('⏸️ 8. deactivate() - Widget被停用');super.deactivate();}// 9. dispose - 最终清理@overridevoid dispose() {print('🗑️ 9. dispose() - 清理资源');WidgetsBinding.instance.removeObserver(this);super.dispose();}// 应用生命周期监听@overridevoid didChangeAppLifecycleState(AppLifecycleState state) {super.didChangeAppLifecycleState(state);print('📱 应用状态改变:$state');switch (state) {case AppLifecycleState.resumed:print('📱 应用回到前台');break;case AppLifecycleState.inactive:print('📱 应用失去焦点');break;case AppLifecycleState.paused:print('📱 应用暂停');break;case AppLifecycleState.detached:print('📱 应用分离');break;}}
}

3.2.3 State管理最佳实践

// 复杂State管理示例
class ComplexStateWidget extends StatefulWidget {@override_ComplexStateWidgetState createState() => _ComplexStateWidgetState();
}class _ComplexStateWidgetState extends State<ComplexStateWidget> {// 状态分组管理late UserController _userController;late AnimationController _animationController;late ScrollController _scrollController;// UI状态bool _isLoading = false;String? _errorMessage;List<User> _users = [];@overridevoid initState() {super.initState();// 初始化控制器_userController = UserController();_animationController = AnimationController(duration: Duration(milliseconds: 300),vsync: this,);_scrollController = ScrollController();// 加载初始数据_loadUsers();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('复杂状态管理')),body: _buildBody(),floatingActionButton: _buildFAB(),);}Widget _buildBody() {if (_isLoading) {return Center(child: CircularProgressIndicator());}if (_errorMessage != null) {return Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Icon(Icons.error, size: 64, color: Colors.red),SizedBox(height: 16),Text(_errorMessage!),ElevatedButton(onPressed: _loadUsers,child: Text('重试'),),],),);}return RefreshIndicator(onRefresh: _loadUsers,child: ListView.builder(controller: _scrollController,itemCount: _users.length,itemBuilder: (context, index) {return UserListItem(user: _users[index],onTap: () => _showUserDetails(_users[index]),onDelete: () => _deleteUser(_users[index]),);},),);}Widget _buildFAB() {return AnimatedBuilder(animation: _animationController,builder: (context, child) {return Transform.scale(scale: 1.0 + (_animationController.value * 0.1),child: FloatingActionButton(onPressed: _addUser,child: Icon(Icons.add),),);},);}// 状态更新方法Future<void> _loadUsers() async {if (!mounted) return;setState(() {_isLoading = true;_errorMessage = null;});try {final users = await _userController.fetchUsers();if (mounted) {setState(() {_users = users;_isLoading = false;});}} catch (e) {if (mounted) {setState(() {_errorMessage = '加载用户失败:$e';_isLoading = false;});}}}void _addUser() {_animationController.forward().then((_) {_animationController.reverse();});// 显示添加用户对话框_showAddUserDialog();}void _deleteUser(User user) async {final confirmed = await _showConfirmDialog('确定删除用户 ${user.name}?');if (confirmed) {setState(() {_users.remove(user);});}}void _showUserDetails(User user) {Navigator.push(context,MaterialPageRoute(builder: (context) => UserDetailPage(user: user),),);}void _showAddUserDialog() {showDialog(context: context,builder: (context) => AddUserDialog(onUserAdded: (user) {setState(() {_users.add(user);});},),);}Future<bool> _showConfirmDialog(String message) async {return await showDialog<bool>(context: context,builder: (context) => AlertDialog(title: Text('确认'),content: Text(message),actions: [TextButton(onPressed: () => Navigator.pop(context, false),child: Text('取消'),),TextButton(onPressed: () => Navigator.pop(context, true),child: Text('确定'),),],),) ?? false;}@overridevoid dispose() {_userController.dispose();_animationController.dispose();_scrollController.dispose();super.dispose();}
}// 用户控制器
class UserController {Future<List<User>> fetchUsers() async {// 模拟网络请求await Future.delayed(Duration(seconds: 2));return [User(name: '张三',email: 'zhangsan@example.com',avatarUrl: 'https://via.placeholder.com/100',bio: 'Flutter开发者',),User(name: '李四',email: 'lisi@example.com',avatarUrl: 'https://via.placeholder.com/100',bio: 'UI设计师',),];}void dispose() {// 清理资源}
}// 用户列表项组件
class UserListItem extends StatelessWidget {final User user;final VoidCallback onTap;final VoidCallback onDelete;const UserListItem({Key? key,required this.user,required this.onTap,required this.onDelete,}) : super(key: key);@overrideWidget build(BuildContext context) {return Dismissible(key: Key(user.email),direction: DismissDirection.endToStart,onDismissed: (direction) => onDelete(),background: Container(color: Colors.red,alignment: Alignment.centerRight,padding: EdgeInsets.only(right: 16),child: Icon(Icons.delete, color: Colors.white),),child: ListTile(leading: CircleAvatar(backgroundImage: NetworkImage(user.avatarUrl),),title: Text(user.name),subtitle: Text(user.email),onTap: onTap,),);}
}

3.3 布局Widget详解

3.3.1 Row和Column深入理解

// Row和Column的完整使用示例
class RowColumnDemo extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Row和Column详解')),body: SingleChildScrollView(padding: EdgeInsets.all(16),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [// Row布局演示_buildSectionTitle('Row布局演示'),_buildRowExamples(),SizedBox(height: 32),// Column布局演示_buildSectionTitle('Column布局演示'),_buildColumnExamples(),SizedBox(height: 32),// 嵌套布局演示_buildSectionTitle('嵌套布局演示'),_buildNestedExample(),],),),);}Widget _buildSectionTitle(String title) {return Container(width: double.infinity,padding: EdgeInsets.symmetric(vertical: 8),child: Text(title,style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),);}Widget _buildRowExamples() {return Column(children: [// 基本Row布局_buildExample('基本Row布局',Row(children: [Container(width: 50, height: 50, color: Colors.red),Container(width: 50, height: 50, color: Colors.green),Container(width: 50, height: 50, color: Colors.blue),],),),// MainAxisAlignment演示_buildExample('MainAxisAlignment.spaceEvenly',Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [_buildColorBox(Colors.red, '1'),_buildColorBox(Colors.green, '2'),_buildColorBox(Colors.blue, '3'),],),),_buildExample('MainAxisAlignment.spaceBetween',Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [_buildColorBox(Colors.red, '1'),_buildColorBox(Colors.green, '2'),_buildColorBox(Colors.blue, '3'),],),),// CrossAxisAlignment演示_buildExample('CrossAxisAlignment.start',Container(height: 100,child: Row(crossAxisAlignment: CrossAxisAlignment.start,children: [_buildColorBox(Colors.red, '1', height: 40),_buildColorBox(Colors.green, '2', height: 60),_buildColorBox(Colors.blue, '3', height: 80),],),),),// Expanded使用_buildExample('Expanded使用',Row(children: [_buildColorBox(Colors.red, '固定'),Expanded(flex: 2,child: _buildColorBox(Colors.green, 'Flex:2'),),Expanded(flex: 1,child: _buildColorBox(Colors.blue, 'Flex:1'),),],),),// Flexible使用_buildExample('Flexible使用',Row(children: [Flexible(child: Container(height: 50,color: Colors.red,child: Center(child: Text('这是一段很长的文本,演示Flexible的效果'),),),),Container(width: 100, height: 50, color: Colors.green),],),),],);}Widget _buildColumnExamples() {return Row(crossAxisAlignment: CrossAxisAlignment.start,children: [// 第一列Expanded(child: Column(children: [_buildExample('MainAxisAlignment.start',Container(height: 150,child: Column(mainAxisAlignment: MainAxisAlignment.start,children: [_buildColorBox(Colors.red, '1'),_buildColorBox(Colors.green, '2'),],),),),_buildExample('MainAxisAlignment.center',Container(height: 150,child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [_buildColorBox(Colors.red, '1'),_buildColorBox(Colors.green, '2'),],),),),],),),SizedBox(width: 16),// 第二列Expanded(child: Column(children: [_buildExample('CrossAxisAlignment.stretch',Container(height: 150,child: Column(crossAxisAlignment: CrossAxisAlignment.stretch,children: [_buildColorBox(Colors.red, '拉伸'),_buildColorBox(Colors.green, '拉伸'),],),),),_buildExample('MainAxisSize.min',Container(height: 150,color: Colors.grey[200],child: Column(mainAxisSize: MainAxisSize.min,children: [_buildColorBox(Colors.red, 'Min'),_buildColorBox(Colors.green, 'Size'),],),),),],),),],);}Widget _buildNestedExample() {return Container(padding: EdgeInsets.all(16),decoration: BoxDecoration(border: Border.all(color: Colors.grey),borderRadius: BorderRadius.circular(8),),child: Column(children: [Text('复杂嵌套布局示例', style: TextStyle(fontWeight: FontWeight.bold)),SizedBox(height: 16),// 模拟社交媒体卡片布局Row(crossAxisAlignment: CrossAxisAlignment.start,children: [// 用户头像CircleAvatar(radius: 25,backgroundColor: Colors.blue,child: Text('U', style: TextStyle(color: Colors.white)),),SizedBox(width: 12),// 内容区域Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [// 用户信息行Row(children: [Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text('用户名',style: TextStyle(fontWeight: FontWeight.bold),),Text('2小时前',style: TextStyle(color: Colors.grey,fontSize: 12,),),],),),Icon(Icons.more_vert, color: Colors.grey),],),SizedBox(height: 8),// 内容文本Text('这是一条社交媒体动态的内容示例...'),SizedBox(height: 12),// 操作按钮行Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [_buildActionButton(Icons.thumb_up, '点赞'),_buildActionButton(Icons.comment, '评论'),_buildActionButton(Icons.share, '分享'),],),],),),],),],),);}Widget _buildActionButton(IconData icon, String label) {return Expanded(child: Row(mainAxisAlignment: MainAxisAlignment.center,children: [Icon(icon, size: 16, color: Colors.grey),SizedBox(width: 4),Text(label, style: TextStyle(color: Colors.grey, fontSize: 12)),],),);}Widget _buildExample(String title, Widget child) {return Container(width: double.infinity,margin: EdgeInsets.only(bottom: 16),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text(title, style: TextStyle(fontSize: 14, color: Colors.grey[600])),SizedBox(height: 8),Container(width: double.infinity,decoration: BoxDecoration(border: Border.all(color: Colors.grey[300]!),borderRadius: BorderRadius.circular(4),),child: child,),],),);}Widget _buildColorBox(Color color, String text, {double? height}) {return Container(width: 60,height: height ?? 50,color: color,child: Center(child: Text(text,style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 12,),),),);}
}

3.3.2 Stack和Positioned高级用法

// Stack和Positioned完整演示
class StackPositionedDemo extends StatefulWidget {@override_StackPositionedDemoState createState() => _StackPositionedDemoState();
}class _StackPositionedDemoState extends State<StackPositionedDemo>with TickerProviderStateMixin {late AnimationController _animationController;late Animation<double> _animation;@overridevoid initState() {super.initState();_animationController = AnimationController(duration: Duration(seconds: 2),vsync: this,);_animation = Tween<double>(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: _animationController, curve: Curves.easeInOut),);_animationController.repeat(reverse: true);}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Stack和Positioned详解')),body: SingleChildScrollView(padding: EdgeInsets.all(16),child: Column(children: [_buildBasicStackExample(),SizedBox(height: 32),_buildPositionedExample(),SizedBox(height: 32),_buildAnimatedStackExample(),SizedBox(height: 32),_buildComplexLayoutExample(),],),),);}Widget _buildBasicStackExample() {return _buildExampleCard('基本Stack布局',Container(height: 200,child: Stack(children: [// 背景容器Container(width: double.infinity,height: double.infinity,decoration: BoxDecoration(gradient: LinearGradient(colors: [Colors.blue[300]!, Colors.blue[600]!],begin: Alignment.topLeft,end: Alignment.bottomRight,),borderRadius: BorderRadius.circular(12),),),// 左上角元素Positioned(top: 16,left: 16,child: Container(padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(20),),child: Text('左上角', style: TextStyle(fontSize: 12)),),),// 右上角元素Positioned(top: 16,right: 16,child: Icon(Icons.favorite, color: Colors.white),),// 居中元素Center(child: Column(mainAxisSize: MainAxisSize.min,children: [Icon(Icons.star, size: 48, color: Colors.white),Text('居中内容',style: TextStyle(color: Colors.white,fontSize: 18,fontWeight: FontWeight.bold,),),],),),// 右下角元素Positioned(bottom: 16,right: 16,child: FloatingActionButton(mini: true,onPressed: () {},child: Icon(Icons.add),),),],),),);}Widget _buildPositionedExample() {return _buildExampleCard('Positioned详细用法',Container(height: 250,child: Stack(children: [// 背景网格CustomPaint(size: Size(double.infinity, double.infinity),painter: GridPainter(),),// Positioned.fill - 填满整个StackPositioned.fill(child: Container(margin: EdgeInsets.all(8),decoration: BoxDecoration(color: Colors.blue.withOpacity(0.1),border: Border.all(color: Colors.blue, width: 2),borderRadius: BorderRadius.circular(8),),child: Center(child: Text('Positioned.fill',style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),),),),),// Positioned.fromRect - 使用矩形定位Positioned.fromRect(rect: Rect.fromLTWH(50, 50, 100, 60),child: Container(decoration: BoxDecoration(color: Colors.green,borderRadius: BorderRadius.circular(8),),child: Center(child: Text('fromRect',style: TextStyle(color: Colors.white, fontSize: 12),),),),),// Positioned.directional - 支持RTLPositioned.directional(textDirection: TextDirection.ltr,start: 16,bottom: 16,child: Container(padding: EdgeInsets.all(8),decoration: BoxDecoration(color: Colors.orange,borderRadius: BorderRadius.circular(8),),child: Text('Directional',style: TextStyle(color: Colors.white, fontSize: 12),),),),// 相对定位Positioned(top: 100,right: 20,width: 80,height: 40,child: Container(decoration: BoxDecoration(color: Colors.purple,borderRadius: BorderRadius.circular(8),),child: Center(child: Text('固定尺寸',style: TextStyle(color: Colors.white, fontSize: 10),),),),),],),),);}Widget _buildAnimatedStackExample() {return _buildExampleCard('动画Stack效果',Container(height: 200,child: AnimatedBuilder(animation: _animation,builder: (context, child) {return Stack(children: [// 背景Container(width: double.infinity,height: double.infinity,decoration: BoxDecoration(color: Colors.grey[100],borderRadius: BorderRadius.circular(12),),),// 动画圆圈1AnimatedPositioned(duration: Duration(milliseconds: 100),left: 20 + (_animation.value * 200),top: 20,child: Container(width: 40,height: 40,decoration: BoxDecoration(color: Colors.red,shape: BoxShape.circle,),),),// 动画圆圈2AnimatedPositioned(duration: Duration(milliseconds: 100),right: 20 + (_animation.value * 200),top: 80,child: Container(width: 40,height: 40,decoration: BoxDecoration(color: Colors.green,shape: BoxShape.circle,),),),// 动画圆圈3AnimatedPositioned(duration: Duration(milliseconds: 100),left: 20 + (_animation.value * 200),bottom: 20,child: Container(width: 40,height: 40,decoration: BoxDecoration(color: Colors.blue,shape: BoxShape.circle,),),),// 中心文本Center(child: Text('动画演示',style: TextStyle(fontSize: 18,fontWeight: FontWeight.bold,color: Colors.grey[700],),),),],);},),),);}Widget _buildComplexLayoutExample() {return _buildExampleCard('复杂Stack布局 - 卡片叠加效果',Container(height: 300,child: Stack(children: [// 卡片1 - 最底层Positioned(top: 40,left: 30,right: 30,bottom: 80,child: Transform.rotate(angle: -0.05,child: _buildCard(Colors.red, '卡片 1'),),),// 卡片2 - 中层Positioned(top: 30,left: 20,right: 20,bottom: 60,child: Transform.rotate(angle: 0.02,child: _buildCard(Colors.green, '卡片 2'),),),// 卡片3 - 顶层Positioned(top: 20,left: 10,right: 10,bottom: 40,child: _buildCard(Colors.blue, '卡片 3'),),// 装饰元素Positioned(top: 0,right: 0,child: Container(width: 60,height: 60,decoration: BoxDecoration(color: Colors.orange,shape: BoxShape.circle,),child: Icon(Icons.star, color: Colors.white),),),// 底部操作栏Positioned(bottom: 0,left: 0,right: 0,child: Container(height: 50,decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.only(bottomLeft: Radius.circular(12),bottomRight: Radius.circular(12),),boxShadow: [BoxShadow(color: Colors.black12,blurRadius: 4,offset: Offset(0, -2),),],),child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [IconButton(icon: Icon(Icons.shuffle),onPressed: () {},),IconButton(icon: Icon(Icons.favorite_border),onPressed: () {},),IconButton(icon: Icon(Icons.share),onPressed: () {},),],),),),],),),);}Widget _buildCard(Color color, String title) {return Container(decoration: BoxDecoration(color: color,borderRadius: BorderRadius.circular(12),boxShadow: [BoxShadow(color: Colors.black26,blurRadius: 8,offset: Offset(0, 4),),],),child: Center(child: Text(title,style: TextStyle(color: Colors.white,fontSize: 24,fontWeight: FontWeight.bold,),),),);}Widget _buildExampleCard(String title, Widget child) {return Card(elevation: 4,child: Padding(padding: EdgeInsets.all(16),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text(title,style: TextStyle(fontSize: 18,fontWeight: FontWeight.bold,color: Colors.grey[700],),),SizedBox(height: 16),child,],),),);}@overridevoid dispose() {_animationController.dispose();super.dispose();}
}// 网格绘制器
class GridPainter extends CustomPainter {@overridevoid paint(Canvas canvas, Size size) {final paint = Paint()..color = Colors.grey[300]!..strokeWidth = 1;// 绘制垂直线for (double x = 0; x <= size.width; x += 20) {canvas.drawLine(Offset(x, 0), Offset(x, size.height), paint);}// 绘制水平线for (double y = 0; y <= size.height; y += 20) {canvas.drawLine(Offset(0, y), Offset(size.width, y), paint);}}@overridebool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

3.4 容器Widget深入理解

3.4.1 Container全面解析

// Container完整功能演示
class ContainerDemo extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Container详解')),body: SingleChildScrollView(padding: EdgeInsets.all(16),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [_buildSectionTitle('基础Container'),_buildBasicContainerExamples(),SizedBox(height: 24),_buildSectionTitle('装饰效果'),_buildDecorationExamples(),SizedBox(height: 24),_buildSectionTitle('变换效果'),_buildTransformExamples(),SizedBox(height: 24),_buildSectionTitle('实际应用案例'),_buildPracticalExamples(),],),),);}Widget _buildSectionTitle(String title) {return Padding(padding: EdgeInsets.symmetric(vertical: 8),child: Text(title,style: TextStyle(fontSize: 20,fontWeight: FontWeight.bold,color: Colors.blue[700],),),);}Widget _buildBasicContainerExamples() {return Column(children: [// 基础Container_buildExample('基础Container - 尺寸和颜色',Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Container(width: 80,height: 80,color: Colors.red,child: Center(child: Text('固定尺寸', style: TextStyle(color: Colors.white))),),Container(padding: EdgeInsets.all(16),color: Colors.green,child: Text('内边距', style: TextStyle(color: Colors.white)),),Container(margin: EdgeInsets.all(8),padding: EdgeInsets.all(8),color: Colors.blue,child: Text('边距+内边距', style: TextStyle(color: Colors.white, fontSize: 10)),),],),),// 对齐方式_buildExample('Container对齐 - Alignment',Row(children: [Expanded(child: Container(height: 100,color: Colors.grey[200],alignment: Alignment.topLeft,child: Container(width: 40,height: 40,color: Colors.red,child: Center(child: Text('TL', style: TextStyle(color: Colors.white, fontSize: 10))),),),),SizedBox(width: 8),Expanded(child: Container(height: 100,color: Colors.grey[200],alignment: Alignment.center,child: Container(width: 40,height: 40,color: Colors.green,child: Center(child: Text('C', style: TextStyle(color: Colors.white))),),),),SizedBox(width: 8),Expanded(child: Container(height: 100,color: Colors.grey[200],alignment: Alignment.bottomRight,child: Container(width: 40,height: 40,color: Colors.blue,child: Center(child: Text('BR', style: TextStyle(color: Colors.white, fontSize: 10))),),),),],),),// 约束演示_buildExample('Container约束 - Constraints',Column(children: [Container(constraints: BoxConstraints(minWidth: 150,minHeight: 50,maxWidth: 200,maxHeight: 80,),color: Colors.orange,child: Text('约束容器\n宽度: 150-200\n高度: 50-80'),),SizedBox(height: 8),Container(constraints: BoxConstraints.expand(height: 60),color: Colors.purple,child: Center(child: Text('扩展宽度,固定高度', style: TextStyle(color: Colors.white)),),),],),),],);}Widget _buildDecorationExamples() {return Column(children: [// 基础装饰_buildExample('BoxDecoration - 边框和圆角',Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Container(width: 80,height: 80,decoration: BoxDecoration(color: Colors.blue,borderRadius: BorderRadius.circular(8),),child: Center(child: Text('圆角', style: TextStyle(color: Colors.white))),),Container(width: 80,height: 80,decoration: BoxDecoration(color: Colors.white,border: Border.all(color: Colors.red, width: 3),borderRadius: BorderRadius.circular(40),),child: Center(child: Text('圆形边框', style: TextStyle(color: Colors.red))),),Container(width: 80,height: 80,decoration: BoxDecoration(gradient: LinearGradient(colors: [Colors.purple, Colors.pink],begin: Alignment.topLeft,end: Alignment.bottomRight,),borderRadius: BorderRadius.circular(8),),child: Center(child: Text('渐变', style: TextStyle(color: Colors.white))),),],),),// 阴影效果_buildExample('BoxShadow - 阴影效果',Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Container(width: 80,height: 80,decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(8),boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.5),spreadRadius: 2,blurRadius: 5,offset: Offset(0, 3),),],),child: Center(child: Text('基础阴影')),),Container(width: 80,height: 80,decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(8),boxShadow: [BoxShadow(color: Colors.blue.withOpacity(0.3),spreadRadius: 0,blurRadius: 10,offset: Offset(0, 0),),],),child: Center(child: Text('发光效果')),),Container(width: 80,height: 80,decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(8),boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1),spreadRadius: 1,blurRadius: 3,offset: Offset(0, 1),),BoxShadow(color: Colors.black.withOpacity(0.2),spreadRadius: 0,blurRadius: 6,offset: Offset(0, 3),),],),child: Center(child: Text('多重阴影')),),],),),// 复杂装饰_buildExample('复杂装饰组合',Container(height: 120,decoration: BoxDecoration(gradient: LinearGradient(colors: [Colors.deepPurple[400]!,Colors.deepPurple[600]!,Colors.deepPurple[800]!,],begin: Alignment.topLeft,end: Alignment.bottomRight,),borderRadius: BorderRadius.only(topLeft: Radius.circular(20),topRight: Radius.circular(20),bottomLeft: Radius.circular(8),bottomRight: Radius.circular(8),),border: Border.all(color: Colors.white.withOpacity(0.3),width: 2,),boxShadow: [BoxShadow(color: Colors.deepPurple.withOpacity(0.3),spreadRadius: 2,blurRadius: 8,offset: Offset(0, 4),),],),child: Stack(children: [// 背景图案Positioned.fill(child: CustomPaint(painter: PatternPainter(),),),// 内容Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Icon(Icons.star, size: 32, color: Colors.white),SizedBox(height: 8),Text('复杂装饰效果',style: TextStyle(color: Colors.white,fontSize: 16,fontWeight: FontWeight.bold,),),],),),],),),),],);}Widget _buildTransformExamples() {return Column(children: [_buildExample('Transform变换效果',Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Container(width: 80,height: 80,transform: Matrix4.rotationZ(0.2),decoration: BoxDecoration(color: Colors.red,borderRadius: BorderRadius.circular(8),),child: Center(child: Text('旋转', style: TextStyle(color: Colors.white))),),Container(width: 80,height: 80,transform: Matrix4.skewX(0.2),decoration: BoxDecoration(color: Colors.green,borderRadius: BorderRadius.circular(8),),child: Center(child: Text('倾斜', style: TextStyle(color: Colors.white))),),Container(width: 80,height: 80,transform: Matrix4.identity()..scale(0.8),decoration: BoxDecoration(color: Colors.blue,borderRadius: BorderRadius.circular(8),),child: Center(child: Text('缩放', style: TextStyle(color: Colors.white))),),],),),],);}Widget _buildPracticalExamples() {return Column(children: [// 卡片样式_buildExample('实用卡片样式',Container(width: double.infinity,decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(12),boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1),spreadRadius: 1,blurRadius: 4,offset: Offset(0, 2),),],),child: Column(children: [// 头部区域Container(width: double.infinity,padding: EdgeInsets.all(16),decoration: BoxDecoration(gradient: LinearGradient(colors: [Colors.blue[400]!, Colors.blue[600]!],),borderRadius: BorderRadius.only(topLeft: Radius.circular(12),topRight: Radius.circular(12),),),child: Row(children: [Icon(Icons.credit_card, color: Colors.white),SizedBox(width: 12),Expanded(child: Text('信用卡',style: TextStyle(color: Colors.white,fontSize: 18,fontWeight: FontWeight.bold,),),),Text('**** 1234',style: TextStyle(color: Colors.white),),],),),// 内容区域Padding(padding: EdgeInsets.all(16),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text('余额', style: TextStyle(color: Colors.grey[600])),Text('¥12,345.67',style: TextStyle(fontSize: 24,fontWeight: FontWeight.bold,),),],),Container(padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),decoration: BoxDecoration(color: Colors.green[100],borderRadius: BorderRadius.circular(20),),child: Text('正常',style: TextStyle(color: Colors.green[700],fontWeight: FontWeight.bold,),),),],),SizedBox(height: 16),Row(children: [Expanded(child: Container(padding: EdgeInsets.symmetric(vertical: 12),decoration: BoxDecoration(border: Border.all(color: Colors.grey[300]!),borderRadius: BorderRadius.circular(8),),child: Center(child: Text('转账')),),),SizedBox(width: 12),Expanded(child: Container(padding: EdgeInsets.symmetric(vertical: 12),decoration: BoxDecoration(color: Colors.blue,borderRadius: BorderRadius.circular(8),),child: Center(child: Text('充值',style: TextStyle(color: Colors.white),),),),),],),],),),],),),),],);}Widget _buildExample(String title, Widget child) {return Container(width: double.infinity,margin: EdgeInsets.only(bottom: 16),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text(title,style: TextStyle(fontSize: 14,fontWeight: FontWeight.w500,color: Colors.grey[700],),),SizedBox(height: 8),child,],),);}
}// 图案绘制器
class PatternPainter extends CustomPainter {@overridevoid paint(Canvas canvas, Size size) {final paint = Paint()..color = Colors.white.withOpacity(0.1)..style = PaintingStyle.stroke..strokeWidth = 1;// 绘制菱形图案for (double x = 0; x < size.width; x += 20) {for (double y = 0; y < size.height; y += 20) {final path = Path();path.moveTo(x + 10, y);path.lineTo(x + 20, y + 10);path.lineTo(x + 10, y + 20);path.lineTo(x, y + 10);path.close();canvas.drawPath(path, paint);}}}@overridebool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

3.5 滚动Widget详解

3.5.1 ListView完整实现

// ListView完整功能演示
class ListViewDemo extends StatefulWidget {@override_ListViewDemoState createState() => _ListViewDemoState();
}class _ListViewDemoState extends State<ListViewDemo> {final ScrollController _scrollController = ScrollController();final List<String> _items = List.generate(50, (index) => '项目 ${index + 1}');bool _showScrollButton = false;@overridevoid initState() {super.initState();_scrollController.addListener(_scrollListener);}void _scrollListener() {if (_scrollController.offset > 200 && !_showScrollButton) {setState(() => _showScrollButton = true);} else if (_scrollController.offset <= 200 && _showScrollButton) {setState(() => _showScrollButton = false);}}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('ListView详解')),body: Column(children: [// 控制面板Container(padding: EdgeInsets.all(16),color: Colors.grey[100],child: Row(children: [ElevatedButton(onPressed: _scrollToTop,child: Text('回到顶部'),),SizedBox(width: 8),ElevatedButton(onPressed: _scrollToBottom,child: Text('滚动到底部'),),SizedBox(width: 8),ElevatedButton(onPressed: _addItem,child: Text('添加项目'),),],),),// ListView区域Expanded(child: Stack(children: [_buildListView(),// 滚动到顶部按钮if (_showScrollButton)Positioned(right: 16,bottom: 16,child: FloatingActionButton(mini: true,onPressed: _scrollToTop,child: Icon(Icons.keyboard_arrow_up),),),],),),],),);}Widget _buildListView() {return ListView.builder(controller: _scrollController,// 性能优化参数itemExtent: 80, // 固定项目高度以提升性能cacheExtent: 500, // 缓存区域大小itemCount: _items.length + 2, // +2 用于头部和尾部itemBuilder: (context, index) {// 头部项目if (index == 0) {return _buildHeader();}// 尾部项目if (index == _items.length + 1) {return _buildFooter();}// 普通项目final itemIndex = index - 1;return _buildListItem(itemIndex);},);}Widget _buildHeader() {return Container(height: 80,decoration: BoxDecoration(gradient: LinearGradient(colors: [Colors.blue[400]!, Colors.blue[600]!],),),child: Center(child: Text('ListView 演示头部',style: TextStyle(color: Colors.white,fontSize: 20,fontWeight: FontWeight.bold,),),),);}Widget _buildFooter() {return Container(height: 80,color: Colors.grey[200],child: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Icon(Icons.done_all, color: Colors.grey[600]),SizedBox(height: 4),Text('已加载 ${_items.length} 个项目',style: TextStyle(color: Colors.grey[600]),),],),),);}Widget _buildListItem(int index) {return Dismissible(key: Key(_items[index]),direction: DismissDirection.endToStart,onDismissed: (direction) {final item = _items[index];setState(() {_items.removeAt(index);});ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('$item 已删除'),action: SnackBarAction(label: '撤销',onPressed: () {setState(() {_items.insert(index, item);});},),),);},background: Container(color: Colors.red,alignment: Alignment.centerRight,padding: EdgeInsets.only(right: 16),child: Icon(Icons.delete, color: Colors.white),),child: Container(height: 80,child: Card(margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),child: ListTile(leading: CircleAvatar(backgroundColor: _getColorForIndex(index),child: Text('${index + 1}'),),title: Text(_items[index]),subtitle: Text('这是第 ${index + 1} 个项目的描述'),trailing: Row(mainAxisSize: MainAxisSize.min,children: [IconButton(icon: Icon(Icons.edit),onPressed: () => _editItem(index),),Icon(Icons.drag_handle, color: Colors.grey),],),onTap: () => _showItemDetails(index),),),),);}Color _getColorForIndex(int index) {final colors = [Colors.red,Colors.green,Colors.blue,Colors.orange,Colors.purple,];return colors[index % colors.length];}void _scrollToTop() {_scrollController.animateTo(0,duration: Duration(milliseconds: 500),curve: Curves.easeInOut,);}void _scrollToBottom() {_scrollController.animateTo(_scrollController.position.maxScrollExtent,duration: Duration(milliseconds: 500),curve: Curves.easeInOut,);}void _addItem() {setState(() {_items.add('新项目 ${_items.length + 1}');});// 滚动到新添加的项目WidgetsBinding.instance.addPostFrameCallback((_) {_scrollController.animateTo(_scrollController.position.maxScrollExtent,duration: Duration(milliseconds: 300),curve: Curves.easeOut,);});}void _editItem(int index) {showDialog(context: context,builder: (context) {String newValue = _items[index];return AlertDialog(title: Text('编辑项目'),content: TextField(controller: TextEditingController(text: newValue),onChanged: (value) => newValue = value,decoration: InputDecoration(labelText: '项目名称',border: OutlineInputBorder(),),),actions: [TextButton(onPressed: () => Navigator.pop(context),child: Text('取消'),),TextButton(onPressed: () {setState(() {_items[index] = newValue;});Navigator.pop(context);},child: Text('保存'),),],);},);}void _showItemDetails(int index) {showModalBottomSheet(context: context,builder: (context) {return Container(height: 300,padding: EdgeInsets.all(16),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text('项目详情',style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),),SizedBox(height: 16),Text('名称: ${_items[index]}'),Text('索引: $index'),Text('位置: 第 ${index + 1} 个'),SizedBox(height: 16),Text('操作:'),SizedBox(height: 8),Row(children: [ElevatedButton(onPressed: () {Navigator.pop(context);_editItem(index);},child: Text('编辑'),),SizedBox(width: 8),ElevatedButton(onPressed: () {Navigator.pop(context);setState(() {_items.removeAt(index);});},style: ElevatedButton.styleFrom(backgroundColor: Colors.red),child: Text('删除'),),],),],),);},);}@overridevoid dispose() {_scrollController.dispose();super.dispose();}
}

3.5.2 GridView和CustomScrollView

// GridView和CustomScrollView演示
class GridViewCustomScrollDemo extends StatefulWidget {@override_GridViewCustomScrollDemoState createState() => _GridViewCustomScrollDemoState();
}class _GridViewCustomScrollDemoState extends State<GridViewCustomScrollDemo>with TickerProviderStateMixin {late TabController _tabController;final ScrollController _scrollController = ScrollController();@overridevoid initState() {super.initState();_tabController = TabController(length: 3, vsync: this);}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('GridView & CustomScrollView'),bottom: TabBar(controller: _tabController,tabs: [Tab(text: 'GridView'),Tab(text: 'CustomScrollView'),Tab(text: '复杂滚动'),],),),body: TabBarView(controller: _tabController,children: [_buildGridViewDemo(),_buildCustomScrollViewDemo(),_buildComplexScrollDemo(),],),);}Widget _buildGridViewDemo() {return Column(children: [// 控制面板Container(padding: EdgeInsets.all(16),color: Colors.grey[100],child: Text('GridView演示 - 网格布局',style: TextStyle(fontWeight: FontWeight.bold),),),Expanded(child: GridView.builder(padding: EdgeInsets.all(16),gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, // 每行2个crossAxisSpacing: 16, // 水平间距mainAxisSpacing: 16, // 垂直间距childAspectRatio: 0.8, // 宽高比),itemCount: 20,itemBuilder: (context, index) {return _buildGridItem(index);},),),],);}Widget _buildGridItem(int index) {final colors = [Colors.red,Colors.green,Colors.blue,Colors.orange,Colors.purple,Colors.teal,];return Container(decoration: BoxDecoration(color: colors[index % colors.length],borderRadius: BorderRadius.circular(12),boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1),blurRadius: 4,offset: Offset(0, 2),),],),child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Icon(_getIconForIndex(index),size: 48,color: Colors.white,),SizedBox(height: 8),Text('项目 ${index + 1}',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 16,),),SizedBox(height: 4),Text('详细描述',style: TextStyle(color: Colors.white70,fontSize: 12,),),],),);}IconData _getIconForIndex(int index) {final icons = [Icons.home,Icons.star,Icons.favorite,Icons.settings,Icons.person,Icons.camera,];return icons[index % icons.length];}Widget _buildCustomScrollViewDemo() {return CustomScrollView(slivers: [// SliverAppBarSliverAppBar(expandedHeight: 200,floating: false,pinned: true,flexibleSpace: FlexibleSpaceBar(title: Text('可折叠标题'),background: Container(decoration: BoxDecoration(gradient: LinearGradient(colors: [Colors.blue[400]!, Colors.blue[600]!],begin: Alignment.topCenter,end: Alignment.bottomCenter,),),child: Center(child: Icon(Icons.landscape, size: 80, color: Colors.white),),),),),// SliverPersistentHeaderSliverPersistentHeader(pinned: true,delegate: CustomSliverDelegate(minHeight: 60,maxHeight: 60,child: Container(color: Colors.grey[200],child: Center(child: Text('固定头部',style: TextStyle(fontWeight: FontWeight.bold),),),),),),// SliverListSliverList(delegate: SliverChildBuilderDelegate((context, index) {return Container(height: 80,margin: EdgeInsets.symmetric(horizontal: 16, vertical: 4),decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.circular(8),boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.1),blurRadius: 2,offset: Offset(0, 1),),],),child: ListTile(leading: CircleAvatar(backgroundColor: Colors.blue,child: Text('${index + 1}'),),title: Text('列表项目 ${index + 1}'),subtitle: Text('这是第 ${index + 1} 个项目'),trailing: Icon(Icons.arrow_forward_ios),),);},childCount: 10,),),// SliverGridSliverPadding(padding: EdgeInsets.all(16),sliver: SliverGrid(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3,crossAxisSpacing: 8,mainAxisSpacing: 8,),delegate: SliverChildBuilderDelegate((context, index) {return Container(decoration: BoxDecoration(color: Colors.orange[300],borderRadius: BorderRadius.circular(8),),child: Center(child: Text('${index + 1}',style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,),),),);},childCount: 12,),),),// SliverToBoxAdapterSliverToBoxAdapter(child: Container(height: 100,margin: EdgeInsets.all(16),decoration: BoxDecoration(color: Colors.green[100],borderRadius: BorderRadius.circular(12),),child: Center(child: Text('单个Widget适配器',style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold,),),),),),],);}Widget _buildComplexScrollDemo() {return NestedScrollView(headerSliverBuilder: (context, innerBoxIsScrolled) {return [SliverAppBar(title: Text('嵌套滚动'),floating: true,snap: true,forceElevated: innerBoxIsScrolled,),];},body: TabBarView(children: [// 第一个标签页ListView.builder(itemCount: 30,itemBuilder: (context, index) {return ListTile(title: Text('嵌套列表项目 ${index + 1}'),leading: Icon(Icons.list),);},),// 第二个标签页  GridView.builder(padding: EdgeInsets.all(8),gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2,crossAxisSpacing: 8,mainAxisSpacing: 8,),itemCount: 20,itemBuilder: (context, index) {return Container(decoration: BoxDecoration(color: Colors.blue[100],borderRadius: BorderRadius.circular(8),),child: Center(child: Text('网格 ${index + 1}')),);},),],),);}@overridevoid dispose() {_tabController.dispose();_scrollController.dispose();super.dispose();}
}// 自定义Sliver委托
class CustomSliverDelegate extends SliverPersistentHeaderDelegate {final double minHeight;final double maxHeight;final Widget child;CustomSliverDelegate({required this.minHeight,required this.maxHeight,required this.child,});@overrideWidget build(BuildContext context, double shrinkOffset, bool overlapsContent) {return SizedBox.expand(child: child);}@overridedouble get maxExtent => maxHeight;@overridedouble get minExtent => minHeight;@overridebool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {return maxHeight != oldDelegate.maxExtent ||minHeight != oldDelegate.minExtent;}
}

http://www.lryc.cn/news/597987.html

相关文章:

  • TimeXer - 重新审视时序预测内的外生变量
  • 【对线面试官】B 树与 B + 树:原理、区别及优劣势分析
  • Java集合去重
  • 借助AI学习开源代码git0.7之九diff-files
  • VUE的学习
  • Linux驱动19 --- FFMPEG
  • kettle插件-kettle数据挖掘ARFF插件
  • Django 科普介绍:从入门到了解其核心魅力
  • 关闭 Chrome 浏览器后,自动删除浏览历史记录
  • 开源项目XBuilder前端框架
  • 从字符串替换到神经网络:AI发展历程中的关键跨越
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 主页-评论用户名词云图实现
  • 高版本Android跨应用广播通信实例
  • tensorflow搭建神经网络
  • 遨游三防平板|国产芯片鸿蒙系统单北斗三防平板,安全高效
  • Node.js特训专栏-实战进阶:18.密码加密与安全传输
  • AI赋能软件工程让测试左移更加可实施
  • 【机器学习之推荐算法】基于K最近邻的协同过滤推荐与基于回归模型的协同过滤推荐
  • LeetCode|Day24|383. 赎金信|Python刷题笔记
  • 微服务-springcloud-springboot-Skywalking详解(下载安装)
  • 用 Function Call 让 AI 主动调用函数(超入门级示例)|保姆级大模型应用开发实战
  • Linux 进程间通信:共享内存详解
  • Spring Boot 3整合Spring AI实战:9轮面试对话解析AI应用开发
  • 【OD机试】矩阵匹配
  • 【分布式锁】什么是分布式锁?分布式锁的作用?
  • redis前期工作:环境搭建-在ubuntu安装redis
  • 实验-OSPF
  • 开立医疗2026年校园招聘
  • 【论文|复现】YOLOFuse:面向多模态目标检测的双流融合框架
  • OSPF路由协议单区域