1、毫无疑问,pubspec.yaml引入
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.8
dio: ^5.8.0+1
provider: ^6.1.5
provider还是有必要存在的
2、来个StatelessWidget
main.dart
import 'package:day01/main_provider.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
MultiProvider(
providers: [ChangeNotifierProvider(create: (context) => MainProvider())],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
Widget build(BuildContext context) {
final provider = Provider.of<MainProvider>(context);
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(provider.text),
ElevatedButton(
onPressed: provider.getList,
child: const Text('请求数据'),
),
],
),
),
);
}
}
这里还是StatelessWidget,状态我暂时是打算全扔到provider里去管理,所以现在莫慌,接下来整provider。
3、补上刚上来的MainProvider
main_provider.dart
import 'dart:convert';
import 'package:day01/bean/base_bean.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
class MainProvider with ChangeNotifier {
String _text = '';
String get text => _text;
void getHello() async {
try{
var response=await Dio().get("http://192.168.5.116:20080/contact/helloworld");
_text=BaseBean.fromJson(response.data).data.toString();
}catch(e){
_text='请求出错了:$e';
}
notifyListeners();
}
}
到这里就可以运行一下,理想效果是:点击一下请求数据按钮,调用provider的getHello方法,然后请求一个demo接口,返回一个hello字符,通过notifyListeners()更新从而显示到页面的Text上。
好了问题来了:我总不能每请求一次就new一个Dio()吧
flutter再简单dio再好用,也禁不住这么个造法啊~做安卓开发的你每次请求都new一个Retrofit或者OkHttp你试试,保证敲你狗头!
4、上菜!Dio封装!
既然都做封装了,单例总得有吧,baseUrl总得有吧,简单的拦截器也总得有吧
dio_util.dart
import 'package:dio/dio.dart';
class DioUtil {
String _baseUrl = 'http://192.168.5.116:20080';
static DioUtil _instance = DioUtil._internal();
Dio? _dio;
factory DioUtil() => _instance;
static DioUtil getInstance() => _instance;
DioUtil._internal() {
_dio = Dio(BaseOptions(baseUrl: _baseUrl));
_dio!.interceptors.add(LogInterceptor(responseBody: true));
}
get(
String url,
Map<String, dynamic>? queryParameters,
Function() load,
Function(dynamic data) success,
Function(String reason) fail,
) async {
load();
var response = await _dio!.get(url, queryParameters: queryParameters);
if (response.statusCode == 200) {
if (response.data['code'] == 200) {
success(response.data);
} else {
fail(response.data['msg']);
}
} else {
fail(response.statusCode!.toString() + "_" + response.statusMessage!);
}
}
post(
String url,
Object? data,
Function() load,
Function(dynamic data) success,
Function(String reason) fail) async{
load();
var response = await _dio!.post(url, data: data);
if (response.statusCode == 200) {
if (response.data['code'] == 200) {
success(response.data);
} else {
fail(response.data['msg']);
}
} else {
fail(response.statusCode!.toString() + "_" + response.statusMessage!);
}
}
addHeader(String key, String value) {
_dio!.options.headers[key] = value;
}
}
好的,单例有了,单例范例在此:
class Singleton {
static final Singleton _singleton = Singleton._internal();
factory Singleton() => _singleton;
Singleton._internal() {
// TODO
}
}
看样子照着抄就行
_dio!.interceptors.add(LogInterceptor(responseBody: true))
这个是添加自带的日志拦截器的,用于打印请求响应
然后给get和post整了个接-化-发
接:触发load()函数,给前端通知,然后开始请求
化:请求到东西没,成功了没,以及各种没成功case
发:直接拿lambda表达式/函数(不管叫啥都是一个意思)把刚才处理好的结果扔出去
最后再写一个加token的方法:
addHeader(String key, String value) {
_dio!.options.headers[key] = value;
}
写这么简单仅为演示,理论上讲应该是扔Map<String,dynamic>的
5、dio封装好了咋用?
上菜!
main_provider.dart
import 'dart:convert';
import 'package:day01/bean/base_bean.dart';
import 'package:day01/dio_util.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
class MainProvider with ChangeNotifier {
String _text = '';
String get text => _text;
void getHello() async {
await DioUtil.getInstance().get("http://192.168.5.116:20080/contact/helloworld",null,(){
_text = "loading";
notifyListeners();
},(data){
BaseBean bean = BaseBean.fromJson(data);
_text = bean.data.toString();
notifyListeners();
},(reason){
_text = reason;
notifyListeners();
});
}
}
齐活!完事!