Flutter网络请求插件fl_dio的使用

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

Flutter网络请求插件fl_dio的使用

fl_dio 是基于 Dio 的扩展,增加了三个拦截器和一个 JsonParse 组件。本文将介绍如何在Flutter项目中使用 fl_dio 插件,并提供一个完整的示例demo。

使用方法

fl_dio 的使用方法与 Dio 基本一致,只需将 Dio 替换为 ExtendedDio 即可。这样可以避免手动编写 try catch 语句,并统一返回 ExtendedResponse

示例代码

以下是使用 fl_dio 插件的完整示例:

import 'dart:convert';

import 'package:device_preview_minus/device_preview_minus.dart';
import 'package:fl_dio/fl_dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey =
    GlobalKey<ScaffoldMessengerState>();
GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

final interceptors = [
  // 数据扩展
  ExtraParamsInterceptor(
      onExtraHeader: (Uri uri, Map<String, dynamic> headers) {
    dioLog('onExtraHeader: $headers');
    return null;
  }, onExtraData: (Uri uri, dynamic data) {
    dioLog('onExtraData: $data');
    return null;
  }, onExtraParams: (Uri uri, Map<String, dynamic> params) {
    dioLog('onExtraParams: $params');
    return null;
  }, onExtraPath: (Uri uri) {
    dioLog('onExtraPath: $uri');
    return null;
  }),

  // 日志打印
  LoggerInterceptor(
      requestDataToJson: true,
      responseDataToJson: true,
      requestQueryParametersToJson: true),

  // debug 调试工具
  DebuggerInterceptor(),

  // cookie 保存和获取
  CookiesInterceptor(),
];

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  // 必须设置 DebuggerInterceptorHelper
  DebuggerInterceptorHelper().navigatorKey = navigatorKey;

  // 设置JsonParse字体颜色
  JsonParse.color = JsonParseColor();

  // 初始化Toast工具
  FlExtended().navigatorKey = navigatorKey;

  // toast 提示
  JsonParse.toastBuilder = (String content) {
    showToast('已复制:$content');
  };

  runApp(DevicePreview(
      enabled: kIsWeb,
      defaultDevice: Devices.ios.iPhone13Mini,
      builder: (context) => MaterialApp(
          navigatorKey: navigatorKey,
          locale: DevicePreview.locale(context),
          theme: ThemeData.light(),
          darkTheme: ThemeData.dark(),
          debugShowCheckedModeBanner: false,
          builder: (BuildContext context, Widget? child) {
            return DevicePreview.appBuilder(context, child);
          },
          home: const Scaffold(body: HomePage()))));
}

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

  [@override](/user/override)
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final dio = ExtendedDio()..interceptors.addAll(interceptors);
  final url =
      'https://lf3-beecdn.bytetos.com/obj/ies-fe-bee/bee_prod/biz_216/bee_prod_216_bee_publish_6676.json';

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      child: Wrap(
          runSpacing: 12,
          spacing: 12,
          alignment: WrapAlignment.center,
          children: [
            ElevatedText('show', onPressed: DebuggerInterceptorHelper().show),
            ElevatedText('showDebugger',
                onPressed: DebuggerInterceptorHelper().showDebugger),
            ElevatedText('hide', onPressed: DebuggerInterceptorHelper().hide),
            ElevatedText('get', onPressed: get),
            ElevatedText('get bytes', onPressed: getBytes),
            ElevatedText('post', onPressed: post),
            ElevatedText('put', onPressed: put),
            ElevatedText('delete', onPressed: delete),
            ElevatedText('patch', onPressed: patch),
            ElevatedText('download', onPressed: download),
            ElevatedText('upload', onPressed: upload),
            ElevatedText('JsonParse', onPressed: () {
              showCupertinoModalPopup(
                  context: context, builder: (_) => const JsonParsePage());
            }),
          ]),
    );
  }

  void getBytes() {
    dio.get(url, options: Options(responseType: ResponseType.bytes));
  }

  void get() {
    dio.get(url);
  }

  void post() {
    dio.post(url,
        data: {'key': 'data'}, queryParameters: {'key': 'queryParameters'});
  }

  void put() {
    showSnackBar('未添加');
  }

  void delete() async {
    showSnackBar('未添加');
  }

  void patch() async {
    showSnackBar('未添加');
  }

  void download() async {
    final dir = await getApplicationCacheDirectory();
    ExtendedDio().download(
        'https://downv6.qq.com/qqweb/QQ_1/android_apk/Android_8.9.28.10155_537147618_64.apk',
        '${dir.path}/file.apk', onReceiveProgress: (int count, int total) {
      dioLog((count / total).toDouble());
    });
  }

  void upload() async {
    showSnackBar('未添加');
  }

  void showSnackBar(String text) {
    scaffoldMessengerKey.currentState
        ?.showSnackBar(SnackBar(content: Text(text)));
  }
}

class ElevatedText extends ElevatedButton {
  ElevatedText(String text, {required super.onPressed, super.key})
      : super(child: Text(text));
}

class JsonParsePage extends StatelessWidget {
  const JsonParsePage({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    final Map<dynamic, dynamic> map =
        jsonDecode('{"name":"BeJson","url":"http://www.bejson.com",'
                '"page":88,"num":88.88,"isNonProfit":true,"address":'
                '{"street":"科技园路.","city":"江苏苏州","country":"中国"},'
                '"links":[{"name":"Google","url":"http://www.google.com"},'
                '{"name":"Baidu","url":"http://www.baidu.com"},'
                '{"name":"SoSo","url":"http://www.SoSo.com"}]}')
            as Map<dynamic, dynamic>;
    final List<dynamic> list = jsonDecode(
            '[{"name":"Google","url":"http://www.google.com"},{"name":"Baidu",'
            '"url":"http://www.baidu.com"},{"name":"SoSo","url":"http://www.SoSo.com"}]')
        as List<dynamic>;
    return Scaffold(
        appBar: AppBar(title: const Text('JsonParse')),
        body: SingleChildScrollView(
            child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(children: [
            const Text('JsonParse'),
            Card(child: JsonParse(map)),
            const Text('JsonParse.list'),
            Card(child: JsonParse.list(list))
          ]),
        )));
  }
}

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

1 回复

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


当然,以下是一个关于如何在Flutter中使用fl_dio(实际上应该是dio包,因为dio是一个非常流行的Flutter/Dart HTTP客户端库,而fl_dio并不是常见的库名)来进行网络请求的示例代码。

首先,确保你已经在pubspec.yaml文件中添加了dio依赖:

dependencies:
  flutter:
    sdk: flutter
  dio: ^4.0.0 # 请根据需要选择最新版本

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

接下来,你可以在你的Flutter项目中创建一个服务类来处理网络请求。以下是一个简单的示例:

import 'package:dio/dio.dart';
import 'dart:convert';

class ApiService {
  final Dio _dio = Dio();

  // Base URL for the API
  final String baseUrl = 'https://api.example.com';

  // Function to make a GET request
  Future<Map<String, dynamic>> getData(String endpoint) async {
    try {
      Response response = await _dio.get('$baseUrl/$endpoint');
      if (response.statusCode == 200) {
        return jsonDecode(response.data);
      } else {
        throw Exception('Failed to load data: ${response.statusCode}');
      }
    } catch (e) {
      throw Exception(e.toString());
    }
  }

  // Function to make a POST request
  Future<Map<String, dynamic>> postData(String endpoint, Map<String, dynamic> data) async {
    try {
      Response response = await _dio.post('$baseUrl/$endpoint', data: data);
      if (response.statusCode == 200 || response.statusCode == 201) {
        return jsonDecode(response.data);
      } else {
        throw Exception('Failed to post data: ${response.statusCode}');
      }
    } catch (e) {
      throw Exception(e.toString());
    }
  }
}

在这个例子中,我们创建了一个ApiService类,该类包含两个方法:getData用于GET请求,postData用于POST请求。_dioDio的实例,用于执行HTTP请求。

现在,你可以在你的Flutter应用中使用这个服务类来进行网络请求。例如:

import 'package:flutter/material.dart';
import 'api_service.dart'; // 假设你的服务类在api_service.dart文件中

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  ApiService _apiService = ApiService();
  String _responseData = '';

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

  Future<void> _fetchData() async {
    try {
      Map<String, dynamic> response = await _apiService.getData('endpoint'); // 替换为实际的API端点
      setState(() {
        _responseData = jsonEncode(response); // 将响应数据转换为字符串以便显示
      });
    } catch (e) {
      setState(() {
        _responseData = 'Error: ${e.toString()}';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Dio Example'),
      ),
      body: Center(
        child: Text(_responseData),
      ),
    );
  }
}

在这个例子中,我们在MyHomePage组件的initState方法中调用_fetchData方法来获取数据,并将响应数据显示在屏幕上。

请注意,这只是一个基本的示例,实际应用中你可能需要处理更多的错误情况、添加请求头、设置超时等。你可以参考dio的官方文档来了解更多高级用法:dio GitHub

回到顶部