07-Flutter鸿蒙页面开发基础:路由、底部导航和常用组件

发布时间:2026/9/27 9:36:31

07-Flutter鸿蒙页面开发基础:路由、底部导航和常用组件
07. Flutter鸿蒙页面开发基础路由、底部导航和常用组件项目跑起来后就可以开始写 Flutter 页面。入门阶段不需要马上引入复杂状态管理先把入口、页面拆分、底部导航、列表、详情页和通用组件写清楚就能支撑大多数小型业务页面。页面目录推荐目录lib ├─ main.dart ├─ app.dart ├─ pages │ ├─ home_page.dart │ ├─ list_page.dart │ ├─ detail_page.dart │ └─ profile_page.dart └─ widgets └─ feature_card.dartApp 入口importpackage:flutter/material.dart;importpages/home_page.dart;voidmain(){runApp(constDemoApp());}classDemoAppextendsStatelessWidget{constDemoApp({super.key});overrideWidgetbuild(BuildContextcontext){returnMaterialApp(debugShowCheckedModeBanner:false,title:Flutter Ohos Demo,theme:ThemeData(colorSchemeSeed:Colors.blue,useMaterial3:true,),home:constHomePage(),);}}底部导航classHomePageextendsStatefulWidget{constHomePage({super.key});overrideStateHomePagecreateState()_HomePageState();}class_HomePageStateextendsStateHomePage{int _index0;finalListWidget_pagesconst[Center(child:Text(首页)),Center(child:Text(列表)),Center(child:Text(我的)),];overrideWidgetbuild(BuildContextcontext){returnScaffold(body:_pages[_index],bottomNavigationBar:NavigationBar(selectedIndex:_index,onDestinationSelected:(value){setState(()_indexvalue);},destinations:const[NavigationDestination(icon:Icon(Icons.home_outlined),label:首页),NavigationDestination(icon:Icon(Icons.list_alt),label:列表),NavigationDestination(icon:Icon(Icons.person_outline),label:我的),],),);}}列表与详情classDemoListPageextendsStatelessWidget{constDemoListPage({super.key});overrideWidgetbuild(BuildContextcontext){finalitemsList.generate(20,(index)第${index1}条内容);returnListView.separated(padding:constEdgeInsets.all(16),itemCount:items.length,separatorBuilder:(_,__)constSizedBox(height:10),itemBuilder:(context,index){returnListTile(shape:RoundedRectangleBorder(borderRadius:BorderRadius.circular(12)),tileColor:Colors.blue.withOpacity(0.08),title:Text(items[index]),trailing:constIcon(Icons.chevron_right),onTap:(){Navigator.of(context).push(MaterialPageRoute(builder:(_)DetailPage(title:items[index]),),);},);},);}}classDetailPageextendsStatelessWidget{finalStringtitle;constDetailPage({super.key,requiredthis.title});overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:Text(title)),body:Center(child:Text(详情内容$title)),);}}组件拆分页面稳定后把重复 UI 抽成组件classFeatureCardextendsStatelessWidget{finalIconDataicon;finalStringtitle;finalStringdesc;finalVoidCallback?onTap;constFeatureCard({super.key,requiredthis.icon,requiredthis.title,requiredthis.desc,this.onTap,});overrideWidgetbuild(BuildContextcontext){returnInkWell(borderRadius:BorderRadius.circular(14),onTap:onTap,child:Container(padding:constEdgeInsets.all(16),decoration:BoxDecoration(color:Colors.white,borderRadius:BorderRadius.circular(14),border:Border.all(color:Colors.black12),),child:Row(children:[Icon(icon,size:32,color:Colors.blue),constSizedBox(width:12),Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(title,style:constTextStyle(fontSize:17,fontWeight:FontWeight.w600)),constSizedBox(height:4),Text(desc,style:constTextStyle(color:Colors.black54)),],),),],),),);}}页面状态不要散落在多个地方页面简单时可以用setState但状态变量要集中管理。例如底部导航只维护一个_index列表页只维护自己的加载状态。不要在父页面和子页面里同时维护相同状态否则刷新时容易不一致。classPageStateT{finalbool loading;finalT?data;finalObject?error;constPageState({this.loadingfalse,this.data,this.error,});}这个小类可以让页面状态更清楚加载中、成功、失败分别对应不同字段。页面尺寸适配鸿蒙设备可能有不同尺寸布局时尽量少写死宽度。优先使用LayoutBuilder(builder:(context,constraints){finalcompactconstraints.maxWidth420;returnPadding(padding:EdgeInsets.all(compact?12:20),child:constText(自适应内容),);},)这样页面在手机、折叠屏或平板场景下更容易继续扩展。(context, constraints) {final compact constraints.maxWidth 420;return Padding(padding: EdgeInsets.all(compact ? 12 : 20),child: const Text(‘自适应内容’),);},)这样页面在手机、折叠屏或平板场景下更容易继续扩展。

相关新闻

如何解决React Native Text Input Mask常见问题:兼容性、性能优化与测试策略终极指南

如何解决React Native Text Input Mask常见问题:兼容性、性能优化与测试策略终极指南

2026/9/3 13:52:43

如何解决React Native Text Input Mask常见问题:兼容性、性能优化与测试策略终极指南 【免费下载链接】react-native-text-input-mask Text input mask for React Native, Android and iOS 项目地址: https://gitcode.com/gh_mirrors/re/react-native-text-input-…

Neural Scene Flow Fields源代码深度剖析:从光流估计到神经辐射场构建

Neural Scene Flow Fields源代码深度剖析:从光流估计到神经辐射场构建

2026/9/8 16:58:56

Neural Scene Flow Fields源代码深度剖析:从光流估计到神经辐射场构建 【免费下载链接】Neural-Scene-Flow-Fields PyTorch implementation of paper "Neural Scene Flow Fields for Space-Time View Synthesis of Dynamic Scenes" 项目地址: https://g…

Saucer多后端支持深度测评:Windows WebView2 vs Linux WebKitGtk vs macOS WKWebView

Saucer多后端支持深度测评:Windows WebView2 vs Linux WebKitGtk vs macOS WKWebView

2026/9/1 11:51:47

Saucer多后端支持深度测评:Windows WebView2 vs Linux WebKitGtk vs macOS WKWebView 【免费下载链接】saucer 🛸 A modern, cross-platform C webview library 项目地址: https://gitcode.com/gh_mirrors/sa/saucer Saucer作为一款现代化的跨平台…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/26 19:14:12

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/27 1:30:29

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/27 1:30:37

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/27 1:30:35

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/27 1:30:34

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/26 16:36:51

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/26 14:29:04

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/26 13:57:22

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/26 23:35:16

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…