Flutter网络请求及下拉刷新插件dio_refresh的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter网络请求及下拉刷新插件dio_refresh的使用

dio_refresh 是一个用于处理 Dio HTTP 客户端请求中自动令牌刷新的 Dart 包。它简化了管理访问和刷新令牌的过程,确保您的 API 请求在访问令牌过期时仍保持认证状态。

特性

  • 自动令牌刷新:当访问令牌过期时,使用自定义刷新回调自动刷新。
  • 可定制:定义自定义逻辑来确定何时需要刷新令牌以及如何生成头信息。
  • 单例令牌管理器:易于存储和检索令牌的单例 TokenManager 类。
  • 无缝集成:设计用于 Dio HTTP 客户端包。

安装

将以下依赖项添加到您的 pubspec.yaml 文件中:

dependencies:
  dio: ^5.0.0
  dio_refresh: ^1.0.0
  flutter:
    sdk: flutter

然后运行:

flutter pub get

入门指南

设置 DioRefreshInterceptor

要使用 DioRefreshInterceptor,您需要定义以下回调:

  • OnRefreshCallback:处理刷新访问令牌的逻辑。
  • ShouldRefreshCallback:确定响应是否需要令牌刷新。
  • TokenHeaderCallback:生成带有访问令牌的头信息。

示例代码

下面是一个完整的示例,展示如何使用 dio_refresh 进行网络请求并实现下拉刷新功能。

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final dio = Dio();

  // Define the TokenManager instance.
  final tokenManager = TokenManager.instance;
  
  @override
  void initState() {
    super.initState();
    
    // Set initial tokens
    tokenManager.setToken(
      TokenStore(
        accessToken: "authToken",
        refreshToken: "refreshToken",
      ),
    );

    // Add the DioRefreshInterceptor.
    dio.interceptors.add(DioRefreshInterceptor(
      tokenManager: tokenManager,
      authHeader: (tokenStore) {
        if (tokenStore.accessToken == null) {
          return {};
        }
        return {
          'Authorization': 'Bearer ${tokenStore.accessToken}',
        };
      },
      shouldRefresh: (response) =>
          response?.statusCode == 401 || response?.statusCode == 403,
      onRefresh: (dio, tokenStore) async {
        final response = await dio.post('/refresh', data: {
          'refresh_token': tokenStore.refreshToken,
        });
        return TokenStore(
          accessToken: response.data['accessToken'],
          refreshToken: response.data['refreshToken'],
        );
      },
    ));
  }

  Future<void> fetchData() async {
    try {
      var response = await dio.get('https://api.example.com/data');
      print(response.data);
    } catch (e) {
      print(e);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Dio Refresh Example'),
      ),
      body: RefreshIndicator(
        onRefresh: () async {
          await fetchData();
        },
        child: Center(
          child: ElevatedButton(
            onPressed: () {
              fetchData();
            },
            child: Text('Fetch Data'),
          ),
        ),
      ),
    );
  }
}

TokenManager 使用

TokenManager 类用于管理访问和刷新令牌。

// Retrieve the singleton instance of TokenManager.
final tokenManager = TokenManager.instance;

// Set new tokens after refreshing.
tokenManager.setToken(TokenStore(
  accessToken: 'newAccessToken',
  refreshToken: 'newRefreshToken',
));

// Access the current access token.
print(tokenManager.accessToken);

API 参考

DioRefreshInterceptor

  • DioRefreshInterceptor:用于处理令牌刷新逻辑的自定义拦截器。
    • tokenManager:用于管理令牌的 TokenManager 实例。
    • authHeader:生成授权头信息的回调。
    • shouldRefresh:确定是否需要刷新的回调。
    • onRefresh:处理刷新逻辑并返回新的 TokenStore 的回调。

TokenManager

  • TokenManager:用于管理令牌的单例类。
    • setToken(TokenStore tokenStore):更新存储的访问和刷新令牌。
    • accessToken:返回当前访问令牌。
    • refreshToken:返回当前刷新令牌。
    • isRefreshing:指示刷新是否正在进行的 ValueNotifier

typedef 回调

  • OnRefreshCallbackFuture<TokenStore> Function(Dio, TokenStore)
    • 处理令牌刷新逻辑。
  • ShouldRefreshCallbackbool Function(Response?)
    • 确定是否需要刷新令牌。
  • TokenHeaderCallbackMap<String, String> Function(TokenStore)
    • 生成请求的授权头信息。

希望这个示例能够帮助你理解如何在 Flutter 应用中使用 dio_refresh 插件进行网络请求和下拉刷新操作。如果有任何问题或建议,请随时提出!


更多关于Flutter网络请求及下拉刷新插件dio_refresh的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网络请求及下拉刷新插件dio_refresh的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,进行网络请求以及实现下拉刷新功能是非常常见的需求。dio是一个非常流行的HTTP客户端库,而dio_refresh是一个基于dioflutter_easyrefresh的封装,它提供了便捷的下拉刷新和上拉加载功能。以下是如何在Flutter项目中结合这两个库来实现网络请求和下拉刷新的示例代码。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加diodio_refresh的依赖:

dependencies:
  flutter:
    sdk: flutter
  dio: ^4.0.4  # 请检查最新版本
  dio_refresh: ^2.2.12  # 请检查最新版本
  flutter_easyrefresh: ^2.2.7  # dio_refresh依赖于flutter_easyrefresh

然后运行flutter pub get来安装这些依赖。

2. 导入必要的包

在你的Dart文件中导入必要的包:

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

3. 配置Dio实例

配置一个全局的Dio实例,以便在整个应用中复用:

var dio = Dio(
  BaseOptions(
    baseUrl: "https://api.example.com/", // 替换为你的API基础URL
    connectTimeout: 30000, // 连接超时时间
    sendTimeout: 30000, // 请求超时时间
    receiveTimeout: 30000, // 响应超时时间
  )
);

4. 使用DioRefresh进行网络请求和下拉刷新

下面是一个完整的示例,展示了如何使用DioRefresh组件来发送网络请求并实现下拉刷新功能:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Dio Refresh Example'),
        ),
        body: DioRefreshWidget(),
      ),
    );
  }
}

class DioRefreshWidget extends StatefulWidget {
  @override
  _DioRefreshWidgetState createState() => _DioRefreshWidgetState();
}

class _DioRefreshWidgetState extends State<DioRefreshWidget> {
  List<dynamic> dataList = [];

  @override
  Widget build(BuildContext context) {
    return EasyRefresh.builder(
      header: ClassicalHeader(),
      footer: ClassicalFooter(),
      onRefresh: () async {
        // 下拉刷新时调用的方法
        await fetchData(true);
      },
      onLoad: () async {
        // 上拉加载时调用的方法(如果需要的话)
        // await fetchMoreData();
      },
      builder: (context, physics, state) {
        return ListView.builder(
          physics: physics,
          itemCount: dataList.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(dataList[index].toString()),
            );
          },
        );
      },
    );
  }

  Future<void> fetchData(bool isRefresh) async {
    try {
      Response<List> response = await dio.get<List>("/your-endpoint"); // 替换为你的API端点
      if (isRefresh) {
        setState(() {
          dataList = response.data;
        });
      } else {
        // 如果是加载更多数据,则追加到列表
        // setState(() {
        //   dataList.addAll(response.data);
        // });
      }
    } catch (e) {
      print("Error fetching data: $e");
      // 处理错误,例如显示SnackBar或Toast
    }
  }
}

解释

  1. 配置Dio实例:在全局范围内配置一个Dio实例,用于发送HTTP请求。
  2. 使用EasyRefreshEasyRefreshdio_refresh依赖的flutter_easyrefresh库中的组件,用于实现下拉刷新和上拉加载功能。
  3. 构建UI:使用ListView.builder来构建列表UI,并在onRefresh回调中调用fetchData方法来刷新数据。
  4. 发送网络请求:在fetchData方法中使用dio.get来发送GET请求,并根据是否是刷新来更新数据列表。

这个示例展示了如何在Flutter中结合diodio_refresh来实现网络请求和下拉刷新功能。你可以根据需要进一步扩展和修改这个示例。

回到顶部