Flutter基础(对接 API)

发布于:2025-06-28 ⋅ 阅读:(16) ⋅ 点赞:(0)

1. 添加依赖

首先在pubspec.yaml中添加http包:

dependencies:
  flutter:
    sdk: flutter
  http: ^1.1.0  # 网络请求库

然后运行flutter pub get来获取依赖包。

2. 创建 API 服务类

创建一个专门的类来处理所有 API 请求,方便统一管理。

import 'dart:convert';  // 用于JSON编解码
import 'package:http/http.dart' as http;  // HTTP请求库

class ApiService {
  // API基础URL(替换为你的API地址)
  final String baseUrl = 'https://api.example.com';
  
  // 添加headers,如认证token
  Map<String, String> get headers => {
    'Content-Type': 'application/json',
    // 'Authorization': 'Bearer your_token_here', // 如果需要认证
  };

  // GET请求示例(获取数据列表)
  Future<List<dynamic>> fetchDataList() async {
    try {
      // 构建请求URL
      final url = Uri.parse('$baseUrl/data');
      
      // 发送GET请求
      final response = await http.get(url, headers: headers);
      
      // 检查响应状态码
      if (response.statusCode == 200) {
        // 请求成功,解析JSON数据
        return json.decode(response.body);
      } else {
        // 请求失败,抛出错误
        throw Exception('请求失败: ${response.statusCode}');
      }
    } catch (e) {
      // 处理异常
      print('API请求错误: $e');
      rethrow;
    }
  }

  // POST请求示例(提交数据)
  Future<Map<String, dynamic>> createData(Map<String, dynamic> data) async {
    try {
      // 构建请求URL
      final url = Uri.parse('$baseUrl/data');
      
      // 发送POST请求,附带JSON数据
      final response = await http.post(
        url,
        headers: headers,
        body: json.encode(data),  // 将Map转为JSON字符串
      );
      
      // 检查响应状态码
      if (response.statusCode == 201) {
        // 创建成功,解析返回的JSON数据
        return json.decode(response.body);
      } else {
        // 请求失败,抛出错误
        throw Exception('创建失败: ${response.statusCode}');
      }
    } catch (e) {
      // 处理异常
      print('API请求错误: $e');
      rethrow;
    }
  }
}

异步编程 vs 同步编程

  • 同步编程:代码按顺序执行,每个操作必须等待前一个操作完成后才能开始。如果某个操作耗时较长(如网络请求),整个程序会被阻塞。
  • 异步编程:当程序发起一个耗时操作时,它不会等待该操作完成,而是继续执行后续代码。当操作完成后,通过回调、Promise、Future 等机制通知程序处理结果。

Future 是异步编程中的一个核心概念,它代表一个异步操作的结果占位符。简单来说,Future 表示一个尚未完成但将来会完成的操作,它有三种状态:

  • 未完成(pending):操作正在进行中,结果尚未就绪。
  • 已完成(completed):操作成功完成,返回结果。
  • 已失败(failed):操作执行失败,返回错误。

使用 Future 的基本操作

// 创建一个返回Future的异步函数
Future<String> fetchData() async {
  // 模拟一个耗时2秒的操作
  await Future.delayed(Duration(seconds: 2));
  return "操作完成";
}

void main() {
  print("开始执行");
  
  // 调用异步函数,立即返回一个Future,不会阻塞后续代码
  Future<String> future = fetchData();
  
  // 注册回调处理结果
  future.then((result) {
    print("结果: $result");
  }).catchError((error) {
    print("错误: $error");
  }).whenComplete(() {
    print("操作结束,无论成功或失败都会执行");
  });
  
  print("继续执行其他任务...");
}

// 输出顺序:
// 开始执行
// 继续执行其他任务...
// (2秒后)
// 结果: 操作完成
// 操作结束,无论成功或失败都会执行
调用这个的代码
import 'dart:convert';
import 'package:http/http.dart' as http;

void main() async {
  // 实例化 ApiService 类
  final apiService = ApiService();

  // 调用 fetchDataList 方法获取数据列表
  try {
    print('正在获取数据列表...');
    final dataList = await apiService.fetchDataList();
    print('数据列表获取成功,共 ${dataList.length} 条数据');
    print('数据内容:$dataList');
  } catch (e) {
    print('获取数据列表失败: $e');
  }

  // 调用 createData 方法提交数据
  try {
    print('\n正在提交数据...');
    final newData = {
      'name': '示例数据',
      'description': '这是一个测试数据',
      'createdAt': DateTime.now().toIso8601String(),
    };
    final response = await apiService.createData(newData);
    print('数据提交成功,返回结果:$response');
  } catch (e) {
    print('提交数据失败: $e');
  }
}

// ApiService 类保持不变
class ApiService {
  // API基础URL(替换为你的API地址)
  final String baseUrl = 'https://api.example.com';
  
  // 添加headers,如认证token
  Map<String, String> get headers => {
    'Content-Type': 'application/json',
    // 'Authorization': 'Bearer your_token_here', // 如果需要认证
  };

  // GET请求示例(获取数据列表)
  Future<List<dynamic>> fetchDataList() async {
    try {
      // 构建请求URL
      final url = Uri.parse('$baseUrl/data');
      
      // 发送GET请求
      final response = await http.get(url, headers: headers);
      
      // 检查响应状态码
      if (response.statusCode == 200) {
        // 请求成功,解析JSON数据
        return json.decode(response.body);
      } else {
        // 请求失败,抛出错误
        throw Exception('请求失败: ${response.statusCode}');
      }
    } catch (e) {
      // 处理异常
      print('API请求错误: $e');
      rethrow;
    }
  }

  // POST请求示例(提交数据)
  Future<Map<String, dynamic>> createData(Map<String, dynamic> data) async {
    try {
      // 构建请求URL
      final url = Uri.parse('$baseUrl/data');
      
      // 发送POST请求,附带JSON数据
      final response = await http.post(
        url,
        headers: headers,
        body: json.encode(data),  // 将Map转为JSON字符串
      );
      
      // 检查响应状态码
      if (response.statusCode == 201) {
        // 创建成功,解析返回的JSON数据
        return json.decode(response.body);
      } else {
        // 请求失败,抛出错误
        throw Exception('创建失败: ${response.statusCode}');
      }
    } catch (e) {
      // 处理异常
      print('API请求错误: $e');
      rethrow;
    }
  }
}

 在 UI 中使用 API 服务

以下是一个简单的 StatefulWidget 示例,展示如何在 UI 中调用上述 API 方法:

import 'package:flutter/material.dart';

class ApiExampleScreen extends StatefulWidget {
  @override
  _ApiExampleScreenState createState() => _ApiExampleScreenState();
}

class _ApiExampleScreenState extends State<ApiExampleScreen> {
  final ApiService _apiService = ApiService();  // 实例化API服务
  List<dynamic> _dataList = [];  // 存储API返回的数据
  bool _isLoading = false;  // 加载状态
  String? _errorMessage;  // 错误信息

  @override
  void initState() {
    super.initState();
    _fetchData();  // 页面加载时获取数据
  }

  // 获取数据方法
  Future<void> _fetchData() async {
    setState(() {
      _isLoading = true;  // 开始加载,显示加载状态
      _errorMessage = null;  // 清除之前的错误信息
    });

    try {
      // 调用API服务的GET方法
      final data = await _apiService.fetchDataList();
      
      // 更新UI状态
      setState(() {
        _dataList = data;  // 存储获取的数据
        _isLoading = false;  // 加载完成
      });
    } catch (e) {
      // 处理异常
      setState(() {
        _errorMessage = e.toString();  // 显示错误信息
        _isLoading = false;  // 加载完成
      });
    }
  }

  // 创建数据方法
  Future<void> _createData() async {
    // 准备要提交的数据
    final newData = {
      'name': '新数据',
      'description': '这是一个示例数据',
      'created_at': DateTime.now().toIso8601String(),
    };

    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });

    try {
      // 调用API服务的POST方法
      final response = await _apiService.createData(newData);
      
      // 更新UI状态
      setState(() {
        _dataList.add(response);  // 将新数据添加到列表
        _isLoading = false;
      });
      
      // 显示成功提示
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('数据创建成功'))
      );
    } catch (e) {
      // 处理异常
      setState(() {
        _errorMessage = e.toString();
        _isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('API示例'),
      ),
      body: Center(
        child: _isLoading
            ? CircularProgressIndicator()  // 显示加载中
            : _errorMessage != null
                ? Text('错误: $_errorMessage')  // 显示错误信息
                : _dataList.isEmpty
                    ? Text('暂无数据')  // 数据为空
                    : ListView.builder(  // 显示数据列表
                        itemCount: _dataList.length,
                        itemBuilder: (context, index) {
                          final item = _dataList[index];
                          return ListTile(
                            title: Text(item['name'] ?? '无名称'),
                            subtitle: Text(item['description'] ?? ''),
                          );
                        },
                      ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _createData,  // 点击按钮创建数据
        child: Icon(Icons.add),
      ),
    );
  }
}

处理 JSON 序列化

对于复杂的数据模型,建议创建对应的 Dart 类并实现序列化方法:

// 数据模型类示例
class DataItem {
  final String id;
  final String name;
  final String description;
  final DateTime createdAt;

  DataItem({
    required this.id,
    required this.name,
    required this.description,
    required this.createdAt,
  });

  // 工厂方法:从JSON数据创建对象
  factory DataItem.fromJson(Map<String, dynamic> json) {
    return DataItem(
      id: json['id'] ?? '',
      name: json['name'] ?? '',
      description: json['description'] ?? '',
      createdAt: DateTime.parse(json['created_at']),
    );
  }

  // 将对象转为JSON
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'description': description,
      'created_at': createdAt.toIso8601String(),
    };
  }
}

// 然后在API服务中使用模型类
Future<List<DataItem>> fetchDataList() async {
  final response = await http.get(Uri.parse('$baseUrl/data'));
  if (response.statusCode == 200) {
    // 将JSON数组转换为对象列表
    return (json.decode(response.body) as List)
        .map((item) => DataItem.fromJson(item))
        .toList();
  } else {
    throw Exception('请求失败');
  }
}


网站公告

今日签到

点亮在社区的每一天
去签到