尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Flutter for OpenHarmony 实战:IP 地址与网络信息查询:HarmonyOS ArkTS API 24 显示本机设备的局域网 IP、运营商等基础信息。

Flutter for OpenHarmony 实战:IP 地址与网络信息查询:HarmonyOS ArkTS API 24 显示本机设备的局域网 IP、运营商等基础信息。 前言跨生态开发的新机遇在移动开发领域我们总是面临着选择与适配。今天你的Flutter应用在Android和iOS上跑得正欢明天可能就需要考虑一个新的平台HarmonyOS鸿蒙。这不是一道选答题而是很多团队正在面对的现实。Flutter的优势很明确——写一套代码就能在两个主要平台上运行开发体验流畅。而鸿蒙代表的是下一个时代的互联生态它不仅仅是手机系统更着眼于未来全场景的体验。将现有的Flutter应用适配到鸿蒙听起来像是一个“跨界”任务但它本质上是一次有价值的技术拓展让产品触达更多用户也让技术栈覆盖更广。不过这条路走起来并不像听起来那么简单。Flutter和鸿蒙从底层的架构到上层的工具链都有着各自的设计逻辑。会遇到一些具体的问题代码如何组织原有的功能在鸿蒙上如何实现那些平台特有的能力该怎么调用更实际的是从编译打包到上架部署整个流程都需要重新摸索。这篇文章想做的就是把这些我们趟过的路、踩过的坑清晰地摊开给你看。我们不会只停留在“怎么做”还会聊到“为什么得这么做”以及“如果出了问题该往哪想”。这更像是一份实战笔记源自真实的项目经验聚焦于那些真正卡住过我们的环节。无论你是在为一个成熟产品寻找新的落地平台还是从一开始就希望构建能面向多端的应用这里的思路和解决方案都能提供直接的参考。理解了两套体系之间的异同掌握了关键的衔接技术不仅能完成这次迁移更能积累起应对未来技术变化的能力。混合工程结构深度解析项目目录架构当Flutter项目集成鸿蒙支持后典型的项目结构会发生显著变化。以下是经过ohos_flutter插件初始化后的项目结构my_flutter_harmony_app/ ├── lib/ # Flutter业务代码基本不变 │ ├── main.dart # 应用入口 │ ├── home_page.dart # 首页 │ └── utils/ │ └── platform_utils.dart # 平台工具类 ├── pubspec.yaml # Flutter依赖配置 ├── ohos/ # 鸿蒙原生层核心适配区 │ ├── entry/ # 主模块 │ │ └── src/main/ │ │ ├── ets/ # ArkTS代码 │ │ │ ├── MainAbility/ │ │ │ │ ├── MainAbility.ts # 主Ability │ │ │ │ └── MainAbilityContext.ts │ │ │ └── pages/ │ │ │ ├── Index.ets # 主页面 │ │ │ └── Splash.ets # 启动页 │ │ ├── resources/ # 鸿蒙资源文件 │ │ │ ├── base/ │ │ │ │ ├── element/ # 字符串等 │ │ │ │ ├── media/ # 图片资源 │ │ │ │ └── profile/ # 配置文件 │ │ │ └── en_US/ # 英文资源 │ │ └── config.json # 应用核心配置 │ ├── ohos_test/ # 测试模块 │ ├── build-profile.json5 # 构建配置 │ └── oh-package.json5 # 鸿蒙依赖管理 └── README.md展示效果图片flutter 实时预览 效果展示运行到鸿蒙虚拟设备中效果展示目录功能代码实现本次开发中容易遇到的问题总结本次开发中用到的技术点功能代码实现IP 地址与网络信息查询组件组件概述IP 地址与网络信息查询组件是一个用于显示本机设备网络信息的工具组件支持显示局域网 IP、运营商、网络类型、设备名称和操作系统等基础信息。该组件采用了现代化的 UI 设计提供了直观的用户界面和流畅的交互体验。核心代码实现1. 组件结构importpackage:flutter/material.dart;importdart:io;importdart:async;classNetworkInfoextendsStatefulWidget{constNetworkInfo({Key?key}):super(key:key);overrideStateNetworkInfocreateState()_NetworkInfoState();}class_NetworkInfoStateextendsStateNetworkInfo{MapString,String_networkInfo{局域网 IP:获取中...,运营商:获取中...,网络类型:获取中...,设备名称:获取中...,操作系统:获取中...,};bool _isLoadingtrue;// 其他方法和构建函数...}2. 网络信息获取逻辑Futurevoid_getNetworkInfo()async{setState((){_isLoadingtrue;});try{// 模拟网络信息获取实际项目中应使用相应的 APIawaitFuture.delayed(constDuration(seconds:1));finalMapString,Stringinfo{局域网 IP:_getLocalIpAddress(),运营商:中国电信,网络类型:WiFi,设备名称:设备名称,操作系统:操作系统版本,};setState((){_networkInfoinfo;_isLoadingfalse;});}catch(e){setState((){_networkInfo{局域网 IP:获取失败,运营商:获取失败,网络类型:获取失败,设备名称:获取失败,操作系统:获取失败,};_isLoadingfalse;});}}3. IP 地址获取String_getLocalIpAddress(){try{// 模拟获取本地 IP 地址实际项目中应使用相应的 APIreturn192.168.1.100;}catch(e){return获取失败;}}4. 复制功能void_copyToClipboard(Stringtext){// 简化的复制功能实际项目中应使用 clipboard 包ScaffoldMessenger.of(context).showSnackBar(SnackBar(content:Text(已复制到剪贴板)),);}5. 信息卡片构建Widget_buildInfoCard(Stringtitle,Stringvalue,IconDataicon){returnContainer(padding:constEdgeInsets.all(16),margin:constEdgeInsets.only(bottom:12),decoration:BoxDecoration(color:Colors.white,borderRadius:BorderRadius.circular(12),border:Border.all(color:Colors.deepPurple.shade100,width:1),boxShadow:[BoxShadow(color:Colors.grey.shade100,spreadRadius:1,blurRadius:4,offset:constOffset(0,2),),],),child:Row(children:[Container(padding:constEdgeInsets.all(12),decoration:BoxDecoration(color:Colors.deepPurple.shade50,borderRadius:BorderRadius.circular(8),),child:Icon(icon,color:Colors.deepPurple,size:24,),),constSizedBox(width:16),Expanded(child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(title,style:TextStyle(fontSize:14,color:Colors.grey.shade600,),),constSizedBox(height:4),Text(value,style:TextStyle(fontSize:16,fontWeight:FontWeight.bold,color:Colors.grey.shade800,),),],),),IconButton(onPressed:()_copyToClipboard(value),icon:constIcon(Icons.copy),tooltip:复制到剪贴板,),],),);}6. 主界面构建overrideWidgetbuild(BuildContextcontext){returnSingleChildScrollView(physics:AlwaysScrollableScrollPhysics(),child:Container(padding:constEdgeInsets.all(24),margin:constEdgeInsets.all(16),decoration:BoxDecoration(color:Colors.white,borderRadius:BorderRadius.circular(16),boxShadow:[BoxShadow(color:Colors.grey.shade200,spreadRadius:2,blurRadius:8,offset:constOffset(0,4),),],),child:Column(crossAxisAlignment:CrossAxisAlignment.start,children:[Text(IP 地址与网络信息查询,style:TextStyle(fontSize:24,fontWeight:FontWeight.bold,color:Colors.deepPurple,),),constSizedBox(height:8),Text(显示本机设备的局域网 IP、运营商等基础信息,style:TextStyle(fontSize:16,color:Colors.grey.shade600,),),constSizedBox(height:32),if(_isLoading)constCenter(child:CircularProgressIndicator(),)elseColumn(children:[_buildInfoCard(局域网 IP,_networkInfo[局域网 IP]!,Icons.network_check),_buildInfoCard(运营商,_networkInfo[运营商]!,Icons.business),_buildInfoCard(网络类型,_networkInfo[网络类型]!,Icons.wifi),_buildInfoCard(设备名称,_networkInfo[设备名称]!,Icons.devices),_buildInfoCard(操作系统,_networkInfo[操作系统]!,Icons.computer),],),constSizedBox(height:24),ElevatedButton(onPressed:_getNetworkInfo,style:ElevatedButton.styleFrom(backgroundColor:Colors.deepPurple,foregroundColor:Colors.white,padding:constEdgeInsets.symmetric(horizontal:32,vertical:16),shape:RoundedRectangleBorder(borderRadius:BorderRadius.circular(8),),minimumSize:constSize(double.infinity,50),),child:constText(刷新信息,style:TextStyle(fontSize:16),),),constSizedBox(height:24),Container(padding:constEdgeInsets.all(16),decoration:BoxDecoration(color:Colors.grey.shade50,borderRadius:BorderRadius.circular(8),border:Border.all(color:Colors.grey.shade200,width:1),),child:Text(提示本工具显示的是本机设备的网络信息包括局域网 IP 地址、运营商信息、网络类型、设备名称和操作系统版本。点击信息卡片右侧的复制图标可以将对应信息复制到剪贴板。,style:TextStyle(fontSize:14,color:Colors.grey.shade600,fontStyle:FontStyle.italic,),),),],),),);}组件使用方法在main.dart文件中我们可以直接导入并使用 NetworkInfo 组件importpackage:flutter/material.dart;importcomponents/network_info.dart;voidmain(){runApp(constMyApp());}classMyAppextendsStatelessWidget{constMyApp({super.key});overrideWidgetbuild(BuildContextcontext){returnMaterialApp(title:Flutter for openHarmony,theme:ThemeData(colorScheme:ColorScheme.fromSeed(seedColor:Colors.deepPurple),useMaterial3:true,),debugShowCheckedModeBanner:false,home:constMyHomePage(title:Flutter for openHarmony),);}}classMyHomePageextendsStatefulWidget{constMyHomePage({super.key,requiredthis.title});finalStringtitle;overrideStateMyHomePagecreateState()_MyHomePageState();}class_MyHomePageStateextendsStateMyHomePage{overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:Text(widget.title),backgroundColor:Colors.deepPurple,),body:SafeArea(child:Padding(padding:constEdgeInsets.all(16.0),child:NetworkInfo(),),),);}}开发中需要注意的点状态管理使用StatefulWidget和setState管理组件状态确保 UI 能够实时响应用户操作。异步操作网络信息获取是一个异步操作需要使用async/await处理并在操作过程中显示加载状态。错误处理需要添加完整的错误处理确保即使发生错误也能将加载状态设置为 false并显示适当的错误信息。平台兼容性不同平台获取网络信息的 API 不同需要考虑跨平台兼容性。布局适配使用SingleChildScrollView处理内容溢出确保在不同屏幕尺寸上都能正常显示。UI 设计保持界面美观大方使用适当的颜色和间距提供良好的用户体验。复制功能实现复制到剪贴板功能时需要考虑不同平台的兼容性建议使用clipboard包。本次开发中容易遇到的问题1. 平台特定 API 不可用问题问题描述在开发过程中使用Platform类的某些属性如localHostname、operatingSystem等可能在某些环境中不可用导致代码执行失败。解决方案使用静态字符串或模拟数据替代可能不可用的平台特定 APIfinalMapString,Stringinfo{局域网 IP:_getLocalIpAddress(),运营商:中国电信,网络类型:WiFi,设备名称:设备名称,// 替代 Platform.localHostname操作系统:操作系统版本,// 替代 Platform.operatingSystem 等};注意事项在实际项目中应使用相应的插件如device_info_plus来获取设备信息添加完整的错误处理确保即使发生错误也能正常显示界面2. 网络信息获取失败问题问题描述在某些网络环境或设备上可能无法获取到网络信息导致显示错误信息。解决方案添加错误处理并在获取失败时显示友好的错误信息try{// 获取网络信息的代码...}catch(e){setState((){_networkInfo{局域网 IP:获取失败,运营商:获取失败,网络类型:获取失败,设备名称:获取失败,操作系统:获取失败,};_isLoadingfalse;});}注意事项提供清晰的错误提示告诉用户网络信息获取失败允许用户通过刷新按钮重新尝试获取网络信息3. 布局溢出问题问题描述在开发过程中当组件内容较多时可能会出现垂直方向的布局溢出问题导致界面显示不完整。解决方案使用SingleChildScrollView包裹整个组件内容确保在内容超出屏幕高度时可以滚动查看overrideWidgetbuild(BuildContextcontext){returnSingleChildScrollView(physics:AlwaysScrollableScrollPhysics(),child:Container(// 组件内容...),);}注意事项确保SingleChildScrollView的父容器有合理的约束避免无限高度的情况对于需要滚动的内容设置physics: AlwaysScrollableScrollPhysics()可以确保即使内容较少时也能滚动4. 复制功能实现问题问题描述在不同平台上实现复制到剪贴板功能可能会有差异需要考虑跨平台兼容性。解决方案使用clipboard包实现跨平台的复制功能在pubspec.yaml文件中添加依赖dependencies:flutter:sdk:flutterclipboard:^0.1.3使用 clipboard 包实现复制功能importpackage:clipboard/clipboard.dart;void_copyToClipboard(Stringtext){FlutterClipboard.copy(text).then((value){ScaffoldMessenger.of(context).showSnackBar(SnackBar(content:Text(已复制到剪贴板)),);});}注意事项确保在使用clipboard包之前已经在pubspec.yaml文件中添加了依赖处理复制操作可能失败的情况提供适当的错误处理5. 加载状态管理问题问题描述在获取网络信息时如果没有正确管理加载状态可能会导致界面一直显示加载指示器或者在加载过程中显示不完整的信息。解决方案在开始获取网络信息时设置_isLoading true在获取完成或失败时设置_isLoading falseFuturevoid_getNetworkInfo()async{setState((){_isLoadingtrue;});try{// 获取网络信息的代码...setState((){_networkInfoinfo;_isLoadingfalse;});}catch(e){setState((){_networkInfo{/* 错误信息 */};_isLoadingfalse;});}}注意事项确保在所有可能的代码路径中都设置_isLoading false在initState中调用_getNetworkInfo()确保组件初始化时就开始获取网络信息总结本次开发中用到的技术点Flutter 核心技术1. 状态管理使用StatefulWidget和setState()管理组件状态实时更新网络信息和加载状态2. 布局与 UI 设计使用Column、Row等布局组件构建界面结构使用Container、BoxDecoration等组件实现卡片式设计使用ElevatedButton实现刷新按钮使用IconButton实现复制功能使用CircularProgressIndicator实现加载指示器3. 滚动处理使用SingleChildScrollView处理内容溢出问题设置AlwaysScrollableScrollPhysics确保滚动流畅4. 主题与样式使用ThemeData统一应用主题使用TextStyle自定义文本样式使用ColorScheme管理应用色彩5. 异步编程使用async/await处理异步操作使用Future.delayed模拟网络请求延迟6. 错误处理使用try-catch处理可能的错误提供错误状态下的 UI 显示功能实现技术1. 网络信息获取模拟网络信息获取实际项目中应使用相应的 API处理网络信息获取失败的情况2. IP 地址获取模拟获取本地 IP 地址实际项目中应使用相应的 API处理 IP 地址获取失败的情况3. 复制功能实现将显示的信息复制到剪贴板的功能提供复制成功的反馈4. 加载状态管理在获取网络信息时显示加载指示器确保加载状态正确更新5. 用户交互支持点击刷新按钮重新获取网络信息支持点击复制图标复制信息到剪贴板跨平台适配技术1. 响应式布局使用SingleChildScrollView确保在不同屏幕尺寸上都能正常显示使用Padding和Margin调整组件间距避免使用固定尺寸尽量使用相对尺寸2. 平台兼容性避免使用平台特定的 API确保在 Flutter 支持的所有平台上都能正常运行考虑鸿蒙平台的特殊性确保代码能够在鸿蒙设备上正常编译和运行3. 性能优化优化网络信息获取逻辑减少不必要的计算使用合理的布局结构避免不必要的重建考虑使用防抖技术优化刷新操作的响应通过本次开发我们不仅实现了 IP 地址与网络信息查询功能还掌握了 Flutter 组件开发的核心技术和跨平台适配的相关知识为后续的鸿蒙平台开发积累了宝贵的经验。
返回列表