Flutter + 鸿蒙跨平台:网络请求与数据列表实战指南

一、项目背景与目标
本项目基于 Flutter + OpenHarmony(开源鸿蒙) 跨平台框架,实现了网络请求能力集成与数据清单列表的完整构建,包含以下核心目标:
集成跨平台网络请求能力,实现 API 数据拉取与解析
实现数据列表渲染、加载状态提示与基础交互优化
适配 OpenHarmony 系统权限体系,完成真机 / 模拟器运行验证
兼容鸿蒙生态第三方库,保障跨平台稳定性与兼容性
二、技术选型与环境配置
1. 核心技术栈说明
根据 OpenHarmony 兼容库清单,本项目选用以下主流三方库,兼顾功能完整性与鸿蒙适配性:
表格
2. 开发环境搭建
2.1 Flutter 鸿蒙适配环境配置
下载鸿蒙适配版 Flutter SDK:

git clone https://gitee.com/openharmony-sig/flutter_flutter.git
cd flutter_flutter
git checkout -b dev origin/dev

配置系统环境变量,将flutter_flutter/bin加入PATH
验证环境:终端执行flutter doctor,确认 OpenHarmony 工具链配置完成
2.2 DevEco Studio 配置
安装 Flutter 与 Dart 插件,重启 IDE
新建 Flutter 项目,选择Flutter Application模板,勾选OpenHarmony平台
配置module.json5网络权限:

"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET",
    "reason": "$string:internet_permission_reason",
    "usedScene": {
      "abilities": ["EntryAbility"],
      "when": "inuse"
    }
  }
]

三、核心功能实现
1. 网络请求功能(基于 dio)
1.1 依赖配置(pubspec.yaml)

dependencies:
  flutter:
    sdk: flutter
  dio: ^5.7.0
  pull_to_refresh: ^2.0.0

执行flutter pub get安装依赖,确保版本与鸿蒙 SDK 兼容。
1.2 网络请求封装代码

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';

class NetworkService {
  final Dio dio = Dio();

  // 初始化请求配置
  NetworkService() {
    dio.options.baseUrl = "https://jsonplaceholder.typicode.com";
    dio.options.connectTimeout = const Duration(seconds: 10);
    dio.options.receiveTimeout = const Duration(seconds: 10);
    // 添加请求拦截器(鸿蒙适配:统一处理权限与跨域)
    dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        options.headers['Content-Type'] = 'application/json';
        return handler.next(options);
      },
    ));
  }

  // 获取数据列表
  Future<List<dynamic>> fetchDataList() async {
    try {
      final response = await dio.get('/posts');
      if (response.statusCode == 200) {
        return response.data;
      } else {
        throw Exception("请求失败,状态码:${response.statusCode}");
      }
    } catch (e) {
      rethrow;
    }
  }
}

2. 数据列表实现(带加载状态)
2.1 完整页面代码

import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'network_service.dart';

class DataListPage extends StatefulWidget {
  const DataListPage({super.key});

  @override
  State<DataListPage> createState() => _DataListPageState();
}

class _DataListPageState extends State<DataListPage> {
  final NetworkService _networkService = NetworkService();
  final RefreshController _refreshController = RefreshController(initialRefresh: false);
  List<dynamic> _dataList = [];
  bool _isLoading = false;

  // 下拉刷新
  Future<void> _onRefresh() async {
    setState(() => _isLoading = true);
    try {
      final data = await _networkService.fetchDataList();
      setState(() => _dataList = data);
      _refreshController.refreshCompleted();
    } catch (e) {
      _refreshController.refreshFailed();
      if (mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("刷新失败:$e")));
    } finally {
      setState(() => _isLoading = false);
    }
  }

  @override
  void initState() {
    super.initState();
    _onRefresh();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("数据清单列表")),
      body: _isLoading && _dataList.isEmpty
          ? const Center(child: CircularProgressIndicator())
          : PullToRefresh(
              controller: _refreshController,
              onRefresh: _onRefresh,
              child: ListView.builder(
                itemCount: _dataList.length,
                itemBuilder: (context, index) {
                  final item = _dataList[index];
                  return Card(
                    margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                    child: Padding(
                      padding: const EdgeInsets.all(16),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text("ID: ${item['id']}", style: const TextStyle(fontWeight: FontWeight.bold)),
                          const SizedBox(height: 8),
                          Text(item['title'], style: const TextStyle(fontSize: 16)),
                          const SizedBox(height: 8),
                          Text(item['body'], style: TextStyle(color: Colors.grey[600])),
                        ],
                      ),
                    ),
                  );
                },
              ),
            ),
    );
  }

  @override
  void dispose() {
    _refreshController.dispose();
    super.dispose();
  }
}

四、鸿蒙适配与运行验证
1. 权限与兼容性处理
网络权限验证:确保module.json5中ohos.permission.INTERNET权限已配置,否则会出现请求失败
三方库适配注意事项:
优先使用 OpenHarmony 已兼容的库版本,避免使用未适配的高版本 API
跨平台请求需处理鸿蒙网络限制,避免 HTTP 明文请求
列表刷新组件需适配鸿蒙触控交互,确保下拉 / 上拉手势响应正常
2. 运行验证步骤
连接鸿蒙模拟器 / 开发板,配置 DevEco Studio 运行设备
点击运行按钮,等待应用安装启动
验证核心功能:
应用启动正常,无权限报错
点击刷新 / 下拉刷新可加载数据
列表渲染正常,卡片样式显示完整
无网络请求异常与崩溃
五、问题排查与优化
1. 常见问题解决
表格
2. 性能优化建议
列表渲染优化:使用ListView.builder懒加载,避免一次性渲染所有数据
网络请求优化:添加请求缓存,减少重复请求
鸿蒙适配优化:避免使用平台特定 API,优先使用跨平台兼容组件
六、总结与扩展
本项目实现了 Flutter + 鸿蒙跨平台网络请求与数据列表的完整开发流程,覆盖了三方库集成、权限配置、适配优化与运行验证全环节。后续可扩展功能包括:
添加上拉加载更多功能,实现分页加载
接入flutter_easy_refresh实现更丰富的加载动画
集成底部导航栏,扩展多页面应用功能
添加数据缓存与离线加载能力,提升应用稳定性
通过本项目,可快速掌握 Flutter 鸿蒙跨平台开发的核心流程,为后续复杂应用开发打下基础。
运行实例
数据清单
加载后

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐