Flutter 三方库 dio 与 pull_to_refresh 的鸿蒙化适配指南
本文基于Flutter for OpenHarmony技术栈,详细介绍了dio网络请求库和pull_to_refresh下拉刷新库在鸿蒙平台上的适配实践。通过设备列表管理场景,展示了完整的跨平台开发方案,包括网络请求封装、列表交互实现、搜索功能与状态管理等核心功能。文章提供了可直接落地的代码示例,如dio的请求重试机制和异常处理,pull_to_refresh的下拉刷新与上拉加载实现,以及带防抖的
Flutter 三方库 dio 与 pull_to_refresh 的鸿蒙化适配指南
欢迎加入开源鸿蒙跨平台社区:→https://openharmonycrossplatform.csdn.net
摘要
本文基于 Flutter for OpenHarmony 技术栈,以设备列表管理场景为例,完整介绍了 dio 网络请求库与 pull_to_refresh 下拉刷新库的鸿蒙化适配实践。从功能实现、性能优化、代码修复到平台验证,提供了一套可直接落地的跨平台开发方案,帮助开发者快速实现兼容开源鸿蒙的高可用 Flutter 应用。
一、项目背景与核心功能
在开源鸿蒙设备管理类应用中,网络请求与列表刷新是高频核心能力。本次适配基于 Flutter 框架,针对设备列表场景,实现了完整的功能闭环:
网络请求能力:使用 dio 库封装了带错误处理与重试机制的网络服务,支持设备列表与详情的拉取
列表交互能力:基于 pull_to_refresh 实现下拉刷新、上拉加载,搭配加载动画与状态提示
搜索与状态管理:支持设备名称 / IP/ID 的实时搜索过滤,覆盖加载中、错误、空数据全场景
UI 与体验优化:使用 Card 组件美化列表项,AppBar 集成搜索框,添加设备状态视觉反馈
二、核心功能实现
2.1 dio 网络请求封装
我们在lib/services/api_service.dart中封装了ApiService类,解决鸿蒙环境下的网络请求适配问题:
实现了通用请求封装,内置重试机制与异常捕获
为设备列表和详情接口添加了缓存策略,减少重复请求
兼容 OpenHarmony 的网络权限与请求限制,确保请求稳定
核心代码示例:
import 'package:dio/dio.dart';
class ApiService {
static final ApiService _instance = ApiService._internal();
factory ApiService() => _instance;
late Dio dio;
// 缓存存储
final Map<String, dynamic> _cache = {};
ApiService._internal() {
dio = Dio(BaseOptions(
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 10),
));
// 添加重试拦截器
dio.interceptors.add(RetryInterceptor(
dio: dio,
retries: 3,
retryDelays: const [
Duration(seconds: 1),
Duration(seconds: 2),
Duration(seconds: 3),
],
));
}
// 获取设备列表(带缓存)
Future<List<Device>> getDeviceList({bool refresh = false}) async {
const cacheKey = 'device_list';
if (!refresh && _cache.containsKey(cacheKey)) {
return _cache[cacheKey];
}
try {
final response = await dio.get('/api/devices');
final list = (response.data['list'] as List).map((e) => Device.fromJson(e)).toList();
_cache[cacheKey] = list;
return list;
} on DioException catch (e) {
// 统一错误处理
throw _handleDioError(e);
}
}
Exception _handleDioError(DioException e) {
switch (e.type) {
case DioExceptionType.connectionTimeout:
return Exception("网络连接超时,请检查网络设置");
case DioExceptionType.receiveTimeout:
return Exception("服务器响应超时");
case DioExceptionType.badResponse:
return Exception("请求失败,状态码:${e.response?.statusCode}");
default:
return Exception("网络请求异常,请稍后重试");
}
}
}
2.2 pull_to_refresh 列表交互实现
在lib/main.dart中,我们基于pull_to_refresh实现了下拉刷新与上拉加载:
class _DeviceListPageState extends State<DeviceListPage> {
final RefreshController _refreshController = RefreshController(initialRefresh: false);
final ApiService _apiService = ApiService();
List<Device> _deviceList = [];
bool _isLoading = true;
String? _errorMsg;
Timer? _searchDebounceTimer;
@override
void initState() {
super.initState();
_fetchDeviceList(refresh: true);
}
// 下拉刷新
void _onRefresh() async {
try {
await _fetchDeviceList(refresh: true);
_refreshController.refreshCompleted();
} catch (e) {
_refreshController.refreshFailed();
}
}
// 上拉加载更多
void _onLoading() async {
try {
// 模拟分页加载
await Future.delayed(const Duration(milliseconds: 1000));
// 若没有更多数据,调用loadNoData()
_refreshController.loadComplete();
} catch (e) {
_refreshController.loadFailed();
}
}
// 带防抖的搜索过滤
void _onSearchChanged(String keyword) {
_searchDebounceTimer?.cancel();
_searchDebounceTimer = Timer(const Duration(milliseconds: 500), () {
setState(() {
// 按设备名称、IP、ID过滤列表
_filteredList = _deviceList.where((device) {
return device.name.contains(keyword) ||
device.ip.contains(keyword) ||
device.id.contains(keyword);
}).toList();
});
});
}
@override
void dispose() {
_refreshController.dispose();
_searchDebounceTimer?.cancel(); // 释放定时器,避免内存泄漏
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: TextField(
decoration: const InputDecoration(
hintText: '搜索设备名称/IP/ID',
border: InputBorder.none,
icon: Icon(Icons.search),
),
onChanged: _onSearchChanged,
),
),
body: _buildBody(),
);
}
Widget _buildBody() {
if (_isLoading) {
return const Center(child: CircularProgressIndicator());
}
if (_errorMsg != null) {
return Center(child: Text(_errorMsg!));
}
if (_filteredList.isEmpty) {
return const Center(child: Text("暂无设备数据"));
}
return SmartRefresher(
controller: _refreshController,
enablePullDown: true,
enablePullUp: true,
onRefresh: _onRefresh,
onLoading: _onLoading,
child: ListView.builder(
itemCount: _filteredList.length,
itemBuilder: (context, index) {
final device = _filteredList[index];
return Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: ListTile(
leading: Icon(
Icons.devices_outlined, // 替换不存在的devices_off图标
color: device.isOnline ? Colors.green : Colors.grey,
),
title: Text(device.name),
subtitle: Text("IP: ${device.ip} | ID: ${device.id}"),
),
);
},
),
);
}
}
三、性能与体验优化
3.1 核心优化点
3.2 关键修复说明
图标兼容性修复:将Icons.devices_off替换为Icons.devices_outlined,解决该图标在鸿蒙环境中不存在的问题
类型错误修复:将Duration(seconds: 0.5)修改为Duration(milliseconds: 500),确保参数类型合规,避免编译错误
四、鸿蒙平台验证
4.1 代码质量检查
执行flutter analyze命令,无语法错误与平台兼容性警告
代码结构清晰,分层明确,符合 Flutter 跨平台开发规范
4.2 构建与运行验证
成功执行flutter build hap命令,无构建错误,生成了兼容开源鸿蒙的 HAP 安装包
应用在鸿蒙设备上可正常运行,网络请求、下拉刷新、搜索过滤等功能均符合预期,无运行崩溃或逻辑异常
4.3 兼容性说明
本次适配使用的dio与pull_to_refresh库均已兼容 Flutter for OpenHarmony 环境,适配过程中未发现平台特有的 API 冲突,所有功能均能在鸿蒙设备上稳定运行。
五、总结与实践建议
本文通过一个完整的设备列表案例,展示了 Flutter 中dio与pull_to_refresh库在开源鸿蒙平台的适配与优化方案。在跨平台开发中,除了基础功能实现,还需要重点关注以下几点:
平台兼容性优先:提前验证三方库在鸿蒙环境的可用性,避免使用平台特有的 API 或图标
性能与体验并重:通过缓存、防抖、资源释放等手段,提升应用在低配置鸿蒙设备上的运行流畅度
完善的状态处理:覆盖加载中、错误、空数据等场景,提升用户体验的完整性
运用实例
更多推荐




所有评论(0)