05-Flutter 鸿蒙实战 05:照片上传功能,image_picker + Multipart 进度上传

发布时间:2026/11/4 17:35:16

05-Flutter 鸿蒙实战 05:照片上传功能,image_picker + Multipart 进度上传 05. Flutter 鸿蒙实战 05照片上传功能image_picker Multipart 进度上传从图库选择照片校验类型和大小再把字节流上传到后端。上传页职责上传页位于lib/features/upload/upload_page.dart。它不是一个简单的按钮页面而是包含选择照片、预览、MIME 校验、大小限制、上传进度、处理状态、照片管理列表等多个状态。页面状态字段比较多但每个都对应真实交互XFile?_file;Uint8List?_bytes;String?_mimeType;String?_error;String?_success;bool _pickingfalse;bool _uploadingfalse;bool _processingfalse;double _progress0;ListAlbumPhoto_photosconst[];_picking表示正在调起图库_uploading表示字节正在上传_processing表示后端正在识别照片并生成故事。三个状态分开页面才能给出准确提示。选择照片项目使用image_picker并且依赖来自 OpenHarmony 适配仓库。选择图片的代码如下finalfileawait_picker.pickImage(source:ImageSource.gallery,imageQuality:92,);if(filenull)return;finalbytesawaitfile.readAsBytes();finalmimeTypelookupMimeType(file.name,headerBytes:bytes.take(16).toList());这里没有只看文件后缀而是用文件名和头部字节一起判断 MIME。移动端上传图片时用户文件来源不可控后缀并不总是可靠。类型和大小校验项目限制最大 20MB并允许常见图片格式if(bytes.length_maxBytes){throwconstFormatException(照片不能超过 20 MB);}if(!const{image/jpeg,image/png,image/webp,image/heic}.contains(mimeType)){throwconstFormatException(仅支持 JPEG、PNG、WebP 和 HEIC 图片);}这一步放在前端做可以减少无效上传。后端仍然应该做最终校验但前端提前提示会让体验更顺。上传照片上传时调用ApiClient.uploadPhotofinalresponseawaitapiClient.uploadPhoto(bytes:bytes,filename:file.name,mimeType:mimeType,onProgress:(value){if(mounted)setState(()_progressvalue);},);页面上对应显示线性进度条if(_uploading)...[constSizedBox(height:16),LinearProgressIndicator(value:_progress),constSizedBox(height:8),Text(正在上传${(_progress*100).round()}%,textAlign:TextAlign.center,),]这种进度来自真实字节写入不是假 loading。大图上传时用户能看到进度变化。上传列表页面进入后会加载当前用户上传过的照片Futurevoid_loadPhotos()async{finalapiAuthScope.of(context).apiClient;setState((){_photosLoadingtrue;_photosErrornull;});try{finalrowsawaitapi.getJsonList(/api/photos);finalphotosrows.whereTypeMapString,dynamic().map(AlbumPhoto.fromJson).toList();setState((){_photosphotos;_photosLoadingfalse;});}catch(exception){setState((){_photosLoadingfalse;_photosError_message(exception);});}}上传页不只负责“新增”还承担照片管理入口查看原图、打开对话、编辑元数据、开始活化、从上传列表移除、删除照片。OpenHarmony 适配注意点image_picker必须使用带 ohos 实现的版本。依赖写法如下image_picker:git:url:https://gitcode.com/openharmony-tpc/flutter_packages.gitpath:packages/image_picker/image_picker如果换成普通依赖Android 可能正常鸿蒙构建就可能缺少平台实现。Flutter 鸿蒙项目选择插件时第一眼要看有没有ohos适配。扩展拆解上传页的状态拆分上传页不能只用一个loading。这个项目拆成了_picking、_uploading、_processing、_photosLoading、_clearingUploads等多个状态。它们分别对应选择图片、上传文件、后端处理、加载照片列表、清空上传列表。boolget_busy_picking||_uploading||_processing;用户选择图片时上传按钮要禁用文件正在上传时清除按钮也要禁用后端正在处理时不能重复提交同一张照片。把状态拆清楚后页面行为才不会混乱。防重复操作照片列表里的删除、移除、活化使用了不同的 Set 保存忙碌状态finalSetString_removing{};finalSetString_deleting{};finalSetString_animating{};这种写法比全局禁用整个页面更细。某张照片正在删除时只禁用这张照片对应的按钮其他照片仍然可以操作。al Set _removing {};final Set _deleting {};final Set _animating {};这种写法比全局禁用整个页面更细。某张照片正在删除时只禁用这张照片对应的按钮其他照片仍然可以操作。
延伸阅读

更多相关文章

2026/11/4 17:33:23

codex接入中转站API无法生成图片:本地适配层排查与归一化方案

最近碰到一个挺典型的事:有朋友把 codex 的接口地址换成了第三方中转服务,聊天、补全、改代码都正常,唯独让他画张图,不是回一句"当前模型不支持图像生成",就是终端里吐半行链接然后卡死。他那套 key 拿去别…

2026/11/4 17:33:23

DeepSeek-V4架构拆解:MoE、mHC与分层注意力工程实践

1. 从一张架构图说起:DeepSeek-V4 到底改了什么第一次看到 DeepSeek-V4 那张架构总览图的时候,我盯着看了差不多二十分钟。不是看不懂,而是信息密度太高——mHC、CSA、HCA、SWA、MoE 这几个模块被画在同一张图里,箭头交错&#xf…

2026/11/4 17:33:23

Git与GitHub入门指南:从零掌握版本控制

1. 为什么每个开发者都需要掌握Git和GitHub刚入行那会儿,我最怕同事说"你把代码commit一下"。当时连commit是什么意思都不懂,更别说pull request、merge这些高级操作了。直到有次误删了三天的工作量,才真正明白版本控制的重要性。G…

2026/11/4 17:33:23

空间数据智能处理:多源融合与决策闭环实践

1. 项目背景与核心价值在数字化转型浪潮中,空间数据的智能化处理正成为城市治理的关键突破口。这个项目本质上是在解决一个行业痛点:如何将分散在不同系统中的空间感知数据(视频、传感器、地理信息等)进行深度融合,形成…

2026/11/4 17:28:22

图片撤回功能的技术实现与优化方案

1. 项目背景与核心价值去年在做一个图片社交项目时,我们团队遇到了一个典型的产品需求:用户发送图片后经常手滑发错,需要实现类似聊天软件的"消息撤回"功能。但深入研究后发现,图片撤回远比文字撤回复杂得多——它不仅要…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

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

2026/11/4 0:03:20

AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年…

2026/11/4 0:03:20

从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你…

2026/11/4 0:03:20

32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

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

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑