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

Flutter Widgets组件详解:从基础到高级

Flutter Widgets组件详解从基础到高级一、Widget基础概念在Flutter中一切都是Widget。Widget是Flutter应用的基本构建块它们描述了UI在某个特定时刻的外观。Flutter的Widget树是应用界面的核心结构。1.1 Widget的分类Flutter Widget主要分为两类Stateless Widget- 无状态组件class MyStatelessWidget extends StatelessWidget { final String title; const MyStatelessWidget({super.key, required this.title}); override Widget build(BuildContext context) { return Text(title); } }Stateful Widget- 有状态组件class MyStatefulWidget extends StatefulWidget { const MyStatefulWidget({super.key}); override StateMyStatefulWidget createState() _MyStatefulWidgetState(); } class _MyStatefulWidgetState extends StateMyStatefulWidget { int _counter 0; void _increment() { setState(() { _counter; }); } override Widget build(BuildContext context) { return Column( children: [ Text(Counter: $_counter), ElevatedButton(onPressed: _increment, child: const Text(Increment)), ], ); } }1.2 Widget树的结构MaterialApp( // 根Widget home: Scaffold( // 页面骨架 appBar: AppBar( // 顶部导航栏 title: Text(Title), ), body: Center( // 居中布局 child: Text(Hello World), ), ), )二、布局Widget详解2.1 Container - 容器组件Container是最常用的布局组件提供了padding、margin、背景色等功能。Container( width: 200, height: 100, margin: const EdgeInsets.all(16), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(8), boxShadow: const [ BoxShadow( color: Colors.black12, blurRadius: 4, offset: Offset(2, 2), ), ], ), child: const Text( Container, style: TextStyle(color: Colors.white), ), )2.2 Row和Column - 线性布局Row- 水平布局Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: const [ Icon(Icons.home), Text(Home), Icon(Icons.settings), ], )Column- 垂直布局Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: const [ Text(Title), Text(Subtitle), Text(Description), ], )2.3 Flex和Expanded - 弹性布局Row( children: [ Expanded( flex: 2, child: Container(color: Colors.red), ), Expanded( flex: 1, child: Container(color: Colors.blue), ), Expanded( flex: 1, child: Container(color: Colors.green), ), ], )2.4 Stack - 层叠布局Stack( alignment: Alignment.center, children: [ Container( width: 200, height: 200, color: Colors.blue, ), const Text( Centered, style: TextStyle(color: Colors.white, fontSize: 24), ), Positioned( top: 10, right: 10, child: const Icon(Icons.star, color: Colors.yellow), ), ], )2.5 Wrap - 流式布局Wrap( spacing: 8, runSpacing: 8, children: [ for (int i 0; i 10; i) Chip( label: Text(Tag $i), backgroundColor: Colors.grey[200], ), ], )三、Material Design Widget3.1 AppBar - 应用栏AppBar( title: const Text(My App), leading: const Icon(Icons.menu), actions: [ IconButton( icon: const Icon(Icons.search), onPressed: () {}, ), IconButton( icon: const Icon(Icons.more_vert), onPressed: () {}, ), ], elevation: 4, backgroundColor: Colors.blue, )3.2 FloatingActionButton - 悬浮按钮FloatingActionButton( onPressed: () {}, child: const Icon(Icons.add), backgroundColor: Colors.blue, elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), )3.3 Card - 卡片组件Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Padding( padding: const EdgeInsets.all(16), child: Column( children: const [ Icon(Icons.person, size: 48), SizedBox(height: 12), Text(John Doe), Text(johnexample.com), ], ), ), )3.4 ListTile - 列表项ListTile( leading: const CircleAvatar( backgroundImage: NetworkImage(https://example.com/avatar.jpg), ), title: const Text(John Doe), subtitle: const Text(Online), trailing: const Icon(Icons.arrow_forward_ios), onTap: () {}, )3.5 Button组件// ElevatedButton - 凸起按钮 ElevatedButton( onPressed: () {}, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue, padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: const Text(Submit), ) // OutlinedButton - 描边按钮 OutlinedButton( onPressed: () {}, style: OutlinedButton.styleFrom( side: const BorderSide(color: Colors.blue), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: const Text(Cancel), ) // TextButton - 文字按钮 TextButton( onPressed: () {}, child: const Text(Learn More), )四、文本和输入Widget4.1 Text - 文本组件const Text( Hello Flutter, style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.blue, fontStyle: FontStyle.italic, decoration: TextDecoration.underline, letterSpacing: 2, height: 1.5, ), textAlign: TextAlign.center, maxLines: 2, overflow: TextOverflow.ellipsis, )4.2 RichText - 富文本RichText( text: TextSpan( style: DefaultTextStyle.of(context).style, children: const [ TextSpan( text: Hello , style: TextStyle(fontWeight: FontWeight.bold), ), TextSpan( text: Flutter, style: TextStyle(color: Colors.blue), ), TextSpan( text: World!, style: TextStyle(fontStyle: FontStyle.italic), ), ], ), )4.3 TextField - 文本输入框TextField( decoration: InputDecoration( labelText: Username, hintText: Enter your username, prefixIcon: const Icon(Icons.person), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), focusedBorder: OutlineInputBorder( borderSide: const BorderSide(color: Colors.blue), borderRadius: BorderRadius.circular(8), ), ), keyboardType: TextInputType.emailAddress, textInputAction: TextInputAction.next, onChanged: (value) { // Handle input changes }, )4.4 TextFormField - 带验证的文本输入TextFormField( decoration: const InputDecoration( labelText: Email, hintText: Enter your email, ), validator: (value) { if (value null || value.isEmpty) { return Please enter your email; } final emailRegex RegExp(r^[\w-\.]([\w-]\.)[\w-]{2,4}$); if (!emailRegex.hasMatch(value)) { return Please enter a valid email; } return null; }, )五、图像和图标Widget5.1 Image - 图片组件// 从网络加载 Image.network( https://example.com/image.jpg, width: 200, height: 200, fit: BoxFit.cover, loadingBuilder: (context, child, loadingProgress) { if (loadingProgress null) return child; return const Center( child: CircularProgressIndicator(), ); }, errorBuilder: (context, error, stackTrace) { return const Icon(Icons.error); }, ) // 从本地资产加载 Image.asset( assets/images/logo.png, width: 100, height: 100, )5.2 Icon - 图标组件const Icon( Icons.home, size: 32, color: Colors.blue, ) // 使用自定义图标字体 Icon( IconData(0xe900, fontFamily: MyIcons), size: 32, )5.3 IconButton - 图标按钮IconButton( icon: const Icon(Icons.favorite), iconSize: 24, color: Colors.red, onPressed: () {}, splashRadius: 20, )六、滚动Widget6.1 SingleChildScrollView - 单子滚动SingleChildScrollView( child: Column( children: [ for (int i 0; i 50; i) ListTile( title: Text(Item $i), ), ], ), )6.2 ListView - 列表视图// ListView.builder - 按需构建 ListView.builder( itemCount: 100, itemBuilder: (context, index) { return ListTile( title: Text(Item $index), ); }, ) // ListView.separated - 带分隔线 ListView.separated( itemCount: 100, separatorBuilder: (context, index) const Divider(), itemBuilder: (context, index) { return ListTile( title: Text(Item $index), ); }, )6.3 GridView - 网格视图GridView.count( crossAxisCount: 2, crossAxisSpacing: 8, mainAxisSpacing: 8, padding: const EdgeInsets.all(16), children: [ for (int i 0; i 12; i) Container( color: Colors.blue[100], child: Center(child: Text(Grid $i)), ), ], ) // GridView.builder GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 8, mainAxisSpacing: 8, ), itemCount: 100, itemBuilder: (context, index) { return Container( color: Colors.blue[100], child: Center(child: Text(Grid $index)), ); }, )七、对话框和弹窗Widget7.1 AlertDialog - 警告对话框showDialog( context: context, builder: (context) AlertDialog( title: const Text(Confirm), content: const Text(Are you sure you want to delete?), actions: [ TextButton( onPressed: () Navigator.pop(context), child: const Text(Cancel), ), ElevatedButton( onPressed: () { // Handle delete Navigator.pop(context); }, child: const Text(Delete), ), ], ), )7.2 SimpleDialog - 简单对话框showDialog( context: context, builder: (context) SimpleDialog( title: const Text(Select Option), children: [ SimpleDialogOption( onPressed: () { Navigator.pop(context, Option 1); }, child: const Text(Option 1), ), SimpleDialogOption( onPressed: () { Navigator.pop(context, Option 2); }, child: const Text(Option 2), ), ], ), )7.3 SnackBar - 轻量级提示ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Text(Message sent successfully), duration: const Duration(seconds: 2), action: SnackBarAction( label: Undo, onPressed: () {}, ), ), )八、自定义Widget8.1 创建自定义StatelessWidgetclass CustomButton extends StatelessWidget { final String text; final VoidCallback onPressed; final Color? color; const CustomButton({ super.key, required this.text, required this.onPressed, this.color, }); override Widget build(BuildContext context) { return ElevatedButton( onPressed: onPressed, style: ElevatedButton.styleFrom( backgroundColor: color ?? Theme.of(context).primaryColor, padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: Text( text, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), ); } }8.2 创建自定义StatefulWidgetclass CounterWidget extends StatefulWidget { const CounterWidget({super.key}); override StateCounterWidget createState() _CounterWidgetState(); } class _CounterWidgetState extends StateCounterWidget { int _count 0; void _increment() setState(() _count); void _decrement() setState(() _count--); void _reset() setState(() _count 0); override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( $_count, style: const TextStyle(fontSize: 48), ), const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ IconButton(onPressed: _decrement, icon: const Icon(Icons.remove)), const SizedBox(width: 16), CustomButton(text: Reset, onPressed: _reset), const SizedBox(width: 16), IconButton(onPressed: _increment, icon: const Icon(Icons.add)), ], ), ], ); } }九、Widget生命周期9.1 StatefulWidget生命周期方法class LifecycleDemo extends StatefulWidget { const LifecycleDemo({super.key}); override StateLifecycleDemo createState() _LifecycleDemoState(); } class _LifecycleDemoState extends StateLifecycleDemo { override void initState() { super.initState(); // 初始化状态只调用一次 } override void didChangeDependencies() { super.didChangeDependencies(); // 依赖变化时调用 } override void didUpdateWidget(covariant LifecycleDemo oldWidget) { super.didUpdateWidget(oldWidget); // Widget更新时调用 } override Widget build(BuildContext context) { // 构建UI return const Placeholder(); } override void dispose() { // 清理资源 super.dispose(); } }十、最佳实践10.1 Widget组合优于继承// 推荐组合现有Widget class UserAvatar extends StatelessWidget { final String url; final double size; const UserAvatar({super.key, required this.url, this.size 48}); override Widget build(BuildContext context) { return CircleAvatar( radius: size / 2, backgroundImage: NetworkImage(url), ); } }10.2 提取复杂Widget// 避免build方法过于庞大 Widget _buildUserCard(User user) { return Card( child: ListTile( leading: UserAvatar(url: user.avatarUrl), title: Text(user.name), subtitle: Text(user.email), ), ); }10.3 使用const构造函数// 对于不变的Widget使用const const Text(Hello World); // 优化性能10.4 合理使用KeyListView.builder( itemBuilder: (context, index) { return ListTile( key: UniqueKey(), // 或ValueKey(item.id) title: Text(Item $index), ); }, )总结Flutter的Widget系统是其核心优势之一。通过合理组合和使用各种Widget你可以构建出丰富多样的UI界面。关键要点理解Widget树结构掌握Container、Row、Column、Stack等基础布局Widget合理选择Widget类型根据场景选择Stateless或Stateful Widget善用Material Design组件AppBar、Card、Button等组件能快速构建美观界面性能优化使用ListView.builder、const构造函数等优化渲染性能代码组织将复杂UI提取为独立Widget保持代码清晰继续探索更多Widget和最佳实践你将能够构建出更加精美和高效的Flutter应用。
http://www.rkmt.cn/news/1372591.html

相关文章:

  • C#中实现左侧折叠导航菜单的示例代码
  • 2026 四川热轧钢管怎么选?西南 TOP 经销商维度拆解:行情、价格与采购指南 - 四川盛世钢联营销中心
  • 为什么别人能跑通RAG+Agent而你总超限?DeepSeek配额底层机制(含quota_limit、burst_capacity、reset_window三参数深度解读)
  • Kubernetes边缘计算部署方案:将K8s延伸到边缘节点
  • phpMyAdmin CVE-2014-8959文件包含漏洞实战解析(Windows平台)
  • Linux端口敲门原理与knockd实战部署指南
  • Kubernetes机器学习平台搭建:构建企业级ML训练环境
  • 2026 四川热轧钢板怎么选?西南 TOP 经销商维度拆解:行情、价格与采购指南 - 四川盛世钢联营销中心
  • 软工第三次
  • 2026年AI论文写作软件盘点:12款神器助你高效完成去痕改写、润色和过检
  • 网络技术05-TCP拥塞控制算法——从CUBIC到BBR的性能进化
  • Python算法基础篇之深度优先搜索(DFS)
  • 前端可访问性:自动化测试工具与实践指南
  • DeepSeek V3发布即颠覆:实测对比V2的12项关键指标,哪些场景必须立刻升级?
  • 用ChatGPT做动态仪表盘?先绕过这8个API响应陷阱——附12个经生产环境验证的Viz-Ready Prompt模板
  • Gemini SQL生成准确率暴跌87%?揭秘模型幻觉的4个致命诱因及实时校验方案
  • 每日大赛场景下如何快速接入多模型API提升开发效率
  • Linux端口敲门实战:用knockd为SSH加一道协议层保险
  • DeepSeek-R1模型压缩到<380MB还能保持98.7%对话准确率?——边缘设备量化微调四步法首次公开
  • 初创公司如何借助Taotoken低成本启动AI产品开发
  • Kubernetes可观测性体系构建:全面监控与故障排查指南
  • 登录+注册 每一分钟 最多请求5次
  • 上海空调移机维修拆装靠谱推荐、鑫诚制冷嘉一制冷本地同城移机拆装维修加氟上门服务 - 卓一科技
  • 江苏储能电池箱实力厂商排行 品质保障维度解析 - 奔跑123
  • 【信息科学与工程学】计算机科学与自动化——第六十二篇 虚拟化算法02
  • 江苏自动化设备外壳厂家实力排行:口碑与硬实力双维度盘点 - 奔跑123
  • 广州搬家行业深度科普:从“黑幕”到“避坑”,认准专业的广州市顺风搬家服务有限公司 - 生活服务
  • 告别低效写作:盘点2026年顶尖配置的的降AI率网站
  • JAVA:字符串拼接
  • 【AI翻译避坑指南】:92%用户忽略的5个ChatGPT翻译陷阱(含术语一致性崩塌、文化错译、被动语态误判),附可直接复用的Prompt模板