Commit e7e593fa authored by 窦文's avatar 窦文

Merge branch 'master' of git.naiterui.com:zouzhisheng/netrain_flutter_app

parents 68242b32 6d512a08
......@@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
<string>9.0</string>
</dict>
</plist>
......@@ -339,7 +339,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
......@@ -426,7 +426,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
......@@ -475,7 +475,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
......
......@@ -24,14 +24,14 @@ class MyApp extends StatelessWidget {
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
initialRoute: "key1",
routes: <String, WidgetBuilder>{
"key1": (context) => Scaffold(
appBar: AppBar(
title: Text("路由"),
),
body: RouterNavigator(title: 'Flutter Demo Home Page'),
),
routes: <String, WidgetBuilder>{
"key1": (context) => MyApp(),
"key2": (context) => Second()
},
),
......@@ -59,8 +59,7 @@ class _RouterNavigatorState extends State<RouterNavigator> {
child: Column(
children: [
_item("跳转", () async {
var result = await Navigator.pushNamed(context, "key2",
arguments: "this is value");
var result = await Navigator.push(context, MaterialPageRoute(builder: (context) => Second()));
print("返回值:$result");
}),
Image.asset(Images.bg_my_01)
......
......@@ -39,7 +39,10 @@ class _RouterNavigatorState extends State<RouterNavigator> {
child: Column(
children: [
_item("跳转", () {
Navigator.popUntil(context,ModalRoute.withName("/"));
Navigator.of(context).popUntil(ModalRoute.withName("key1"));
}),
_item("跳转", () {
Navigator.pushNamed(context,"key2");
})
],
),
......
import 'dart:ffi';
import 'dart:html';
import 'package:flutter/material.dart';
class textDemo extends StatelessWidget {
// const ({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
color: Colors.blue,
child:Text (
"文本,我是个文本 woeijaoijfioasjfajfaojfoiasjfidsjfajf危机哦娃儿哦i啊就哦发i家阿减肥哦i阿减肥里挖掘佛i挖掘安抚啊发生放假啊师傅就撒就啊说",
maxLines: 10,
overflow: TextOverflow.ellipsis,
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.orange,
),
),
);
}
}
class buttonDemo extends StatelessWidget {
// const ({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: [
RaisedButton(
onPressed: (){},
child:Text("漂浮按钮")
),
FlatButton(
onPressed: (){},
child: Text("扁平按钮")
),
FlatButton.icon(
onPressed: (){},
icon: Icon(Icons.outbound),
label: Text("按钮"),
color: Colors.black,
textColor: Colors.white,
),
OutlineButton(onPressed: (){},
child: Text("边框按钮"),
),
IconButton(
onPressed: (){},
icon: Icon(Icons.access_alarm),
)
],
);
}
}
class imageiconDemo extends StatelessWidget {
// const ({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: [
Icon(Icons.add),
IconButton(onPressed: (){}, icon: Icon(Icons.home)),
Image.network("http://www.baidu.com/baidu.php?url=a00000KEJeCxDFezEVpFL9_MH8XSqbHklw_maA_-0O-JAG-gv2I-uvEAQqh-teALqpO_NZN1EbyMj5iOpf3Z1ZREUPx5_1lniEkZj6mijxFoM8VqoaPcH0KOxWwCyPbmri5Hlwk-A8u4pBUbGLW2x882fEua1eOAEbBWTdTqxEMA631a3yr2qBWOz88FPpAVsair-sXakr4y6eguntj86fZCDab3.DR_aOQZsYpb2glyIiUr2s1f_uQr1Fv20.U1Yk0ZDqVSXS_0KY5IissIpS_QMU8pi110KGUHY1PWT0Iybq0ZKGujYk0APGujY1rjc0mhbqn10k0AuY5H00TA6qn0KET1Ys0AFL5H00UMfqn0K1XWY0ThIYmyTqn0K8IM0qna3snj0snj0sn0K-ThTqn0KYTh7buHYdrH0knHm0mhwGujdKnWT1rj0sPHnLPYm1fHndrRmdrH64rjDkwjT3PHcsPsKbmvPb5fK9TdqGuAnqujcVmhwbX0KzIjY3P1T0TgKGujYs0Z7Wpyfqn0K9mWYsg100TZ0qn0KVIZ0qn0KbuAqs5H00ThCqn0KYIgnqnHT1P1DYnWD3P1nYP1RznWDYnW60mynqnfKsUWYs0ZK9I7qhUA7M5H00ugwGujYVnfK9TLKWm1Ys0ZNspy4Wm1Ys0AuWIgfqn0K9uAu_myTqnfKLuMFEUHY0mMfqnfKzug7Y5HDvnWRLnW64rHTvrjm0Tv-b5Hbsn16Lm179n1F9nHRvrj60ULfqn0KETMKY5H0WnaPDw-fWnansc10Wna3sc10WwDuRc10WwDuR0AVG5H00UgfqnWfkn0KVm1Ys0AdWgvuzUvYqn0Kbmy4dmhNxTAk9Uh-bT1Ys0A7bTgbqVSXS_0K9uZ7Y5H00pgPWUjYs0Z7VIjYs0A7bgLPEIgFWuHYsczn0mLFW5HRkrjcL",
fit: BoxFit.fitWidth
),
Image.asset("ic_home_normal.png")
],
);
return Container(
);
}
}
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:netrain_flutter_app/xuehao/list_page.dart';
import 'laishanqi/Stateful_page.dart';
import 'laishanqi/Stateless_page.dart';
......@@ -41,6 +42,7 @@ class MyApp extends StatelessWidget {
"layout": (context) => LayoutPage(),
"photo": (context) => PhotoApp(),
"register": (context) => RegisterPage(),
"listPage":(context) => List_Page(),
},
), onWillPop: ()async{
Fluttertoast.showToast(msg: "退出");
......@@ -80,6 +82,7 @@ class _RouterNavigatorState extends State<RouterNavigator> {
_item("拍照页面", PhotoApp(), 'photo'),
_item("登陆", LoginPage(), 'login'),
_item("登录网络请求", LoginRequestPage(), 'loginRequest'),
_item("listview页面",List_Page(),'listPage'),
],
),
);
......
import 'package:json_annotation/json_annotation.dart';
class Car{
//构造函数
Car({
this.name,
this.imageUrl,
});
String name;
String imageUrl;
}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'Car.dart';
class List_Page extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ListPageState();
}
EasyRefreshController _controller = EasyRefreshController();
class _ListPageState extends State<List_Page> {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "listPage",
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text("ListView"),
centerTitle: true,
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back_ios),
),
),
body: EasyRefresh(
header: MaterialHeader(),
footer: MaterialFooter(),
enableControlFinishRefresh: true,
enableControlFinishLoad: true,
controller: _controller,
child: ListView.builder(
itemCount: datas.length,
itemBuilder: _getDatas,
),
onRefresh: () async {
setState(() {
refreshData();
});
},
onLoad: () async {},
),
));
}
Widget _getDatas(BuildContext context, int position) {
return Container(
child: GestureDetector(
child: Card(
elevation: 6,
shadowColor: Colors.redAccent,
margin: EdgeInsets.fromLTRB(16, 20, 16, 20),
child: Column(
children: [
SizedBox(height: 20),
Text(datas[position].name),
SizedBox(height: 10),
Image.network(
datas[position].imageUrl,
width: 340,
height: 200,
),
SizedBox(height: 20),
],
),
),
onTap: () {
var data = datas[position];
Fluttertoast.showToast(msg: "我点击了${data.name}");
},
));
}
}
Future<void> refreshData() async {
await Future.delayed(Duration(seconds: 3), () {
for (int i = 0; i < datas.length; i++) {
datas[i].name = "刷新后的数据$i";
}
_controller.finishRefresh(success: true);
});
}
//定义一个全局的变量:模型数组
List<Car> datas = [
Car(
name: '保时捷918 Spyder',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-7d8be6ebc4c7c95b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '兰博基尼Aventador',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-e3bfd824f30afaac?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '法拉利Enzo',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-a1d64cf5da2d9d99?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: 'Zenvo ST1',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-bf883b46690f93ce?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '迈凯伦F1',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-5a7b5550a19b8342?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '萨林S7',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-2e128d18144ad5b8?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '科尼赛克CCR',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-01ced8f6f95219ec?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '布加迪Chiron',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-7fc8359eb61adac0?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '轩尼诗Venom GT',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-d332bf510d61bbc2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '西贝尔Tuatara',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-3dd9a70b25ae6bc9?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
)
];
import 'Network/HttpManager.dart';
import 'Network/BaseHttpModel.dart';
import 'Network/UrlPath.dart';
/// 所有接口类
class LoginApi {
///示例请求
static loginRequest(Map<String, dynamic> param) {
return HttpManager.getInstance().request('auth/oauth/token', parameters: param, onResult: (data,errorMsg){
BaseHttpModel httpModel = data;
print(httpModel.data);
});
}
}
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'Network/Api.dart';
import 'LoginApi.dart';
class LoginRequestPage extends StatefulWidget {
......@@ -20,7 +20,7 @@ class _LoginState extends State<LoginRequestPage> {
map['client_id'] = 'app';
map['client_secret'] = '123456';
map['platform'] = '0';
Api.request(map);
LoginApi.loginRequest(map);
}
@override
......
import 'HttpManager.dart';
import 'UrlPath.dart';
/// 所有接口类
class Api {
///示例请求
static request(Map<String, dynamic> param) {
return HttpManager.getInstance().get(UrlPath.baseUrl + 'auth/oauth/token', params: param);
}
}
import 'package:json_annotation/json_annotation.dart';
part 'BaseHttpModel.g.dart';
@JsonSerializable()
class BaseHttpModel{
final data;
final code;
final msg;
BaseHttpModel(this.data, this.code, this.msg);
factory BaseHttpModel.fromJson(Map<String, dynamic> json) => _$BaseHttpModelFromJson(json);
Map<String, dynamic> toJson() => _$BaseHttpModelToJson(this);
bool isSuccess(){
return this.code == 200;
}
String errorMsg() {
return this.msg.length > 0 ? this.msg : '网络有误,请稍后再试';
}
}
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'BaseHttpModel.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
BaseHttpModel _$BaseHttpModelFromJson(Map<String, dynamic> json) {
return BaseHttpModel(
json['data'],
json['code'],
json['msg'],
);
}
Map<String, dynamic> _$BaseHttpModelToJson(BaseHttpModel instance) =>
<String, dynamic>{
'data': instance.data,
'code': instance.code,
'msg': instance.msg,
};
///错误编码
class Code {
///网络错误
static const NETWORK_ERROR = -1;
///网络超时
static const NETWORK_TIMEOUT = -2;
///网络返回数据格式化一次
static const NETWORK_JSON_EXCEPTION = -3;
static const SUCCESS = 200;
static errorHandleFunction(code, message, noTip) {
if (noTip) {
return message;
}
return message;
}
}
import 'dart:collection';
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:convert/convert.dart';
///参数加密工具
class DataHelper {
static encryptParams(Map<String, dynamic> map) {
var buffer = StringBuffer();
map.forEach((key, value) {
buffer.write(key);
buffer.write(value);
});
buffer.write("SERECT");
var sign = string2MD5(buffer.toString());
print("sign--->" + sign);
return sign;
}
static string2MD5(String data) {
var content = new Utf8Encoder().convert(data);
var digest = md5.convert(content);
return hex.encode(digest.bytes);
}
}
import 'package:dio/dio.dart';
///日志拦截器
class DioLogInterceptor extends Interceptor {
///请求前
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
String requestStr = "\n==================== REQUEST ====================\n"
"- URL:\n${options.baseUrl + options.path}\n"
"- METHOD: ${options.method}\n";
requestStr += "- HEADER:\n${options.headers.mapToStructureString()}\n";
final data = options.data;
if (data != null) {
if (data is Map)
requestStr += "- BODY:\n${data.mapToStructureString()}\n";
else if (data is FormData) {
final formDataMap = Map()
..addEntries(data.fields)
..addEntries(data.files);
requestStr += "- BODY:\n${formDataMap.mapToStructureString()}\n";
} else
requestStr += "- BODY:\n${data.toString()}\n";
}
print(requestStr);
handler.next(options);
}
///出错前
@override
void onError(DioError err, ErrorInterceptorHandler handler) {
String errorStr = "\n==================== RESPONSE ====================\n"
"- URL:\n${err.requestOptions.baseUrl + err.requestOptions.path}\n"
"- METHOD: ${err.requestOptions.method}\n";
errorStr +=
"- HEADER:\n${err.response.headers.map.mapToStructureString()}\n";
if (err.response != null && err.response.data != null) {
print('╔ ${err.type.toString()}');
errorStr += "- ERROR:\n${_parseResponse(err.response)}\n";
} else {
errorStr += "- ERRORTYPE: ${err.type}\n";
errorStr += "- MSG: ${err.message}\n";
}
print(errorStr);
handler.next(err);
}
///响应前
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
String responseStr =
"\n==================== RESPONSE ====================\n"
"- URL:\n${response.requestOptions.uri}\n";
responseStr += "- HEADER:\n{";
response.headers.forEach(
(key, list) => responseStr += "\n " + "\"$key\" : \"$list\",");
responseStr += "\n}\n";
responseStr += "- STATUS: ${response.statusCode}\n";
if (response.data != null) {
responseStr += "- BODY:\n ${_parseResponse(response)}";
}
printWrapped(responseStr);
handler.next(response);
}
void printWrapped(String text) {
final pattern = new RegExp('.{1,800}'); // 800 is the size of each chunk
pattern.allMatches(text).forEach((match) => print(match.group(0)));
}
String _parseResponse(Response response) {
String responseStr = "";
var data = response.data;
if (data is Map)
responseStr += data.mapToStructureString();
else if (data is List)
responseStr += data.listToStructureString();
else
responseStr += response.data.toString();
return responseStr;
}
}
///Map拓展,MAp转字符串输出
extension Map2StringEx on Map {
String mapToStructureString({int indentation = 2}) {
String result = "";
String indentationStr = " " * indentation;
if (true) {
result += "{";
this.forEach((key, value) {
if (value is Map) {
var temp = value.mapToStructureString(indentation: indentation + 2);
result += "\n$indentationStr" + "\"$key\" : $temp,";
} else if (value is List) {
result += "\n$indentationStr" +
"\"$key\" : ${value.listToStructureString(indentation: indentation + 2)},";
} else {
result += "\n$indentationStr" + "\"$key\" : \"$value\",";
}
});
result = result.substring(0, result.length - 1);
result += indentation == 2 ? "\n}" : "\n${" " * (indentation - 1)}}";
}
return result;
}
}
///List拓展,List转字符串输出
extension List2StringEx on List {
String listToStructureString({int indentation = 2}) {
String result = "";
String indentationStr = " " * indentation;
if (true) {
result += "$indentationStr[";
this.forEach((value) {
if (value is Map) {
var temp = value.mapToStructureString(indentation: indentation + 2);
result += "\n$indentationStr" + "\"$temp\",";
} else if (value is List) {
result += value.listToStructureString(indentation: indentation + 2);
} else {
result += "\n$indentationStr" + "\"$value\",";
}
});
result = result.substring(0, result.length - 1);
result += "\n$indentationStr]";
}
return result;
}
}
import 'package:dio/dio.dart';
import 'Code.dart';
import 'DioLogInterceptor.dart';
import 'Loading.dart';
import 'ResponseInterceptor.dart';
import 'ResultData.dart';
import 'package:netrain_flutter_app/zhangfeng/Network/BaseHttpModel.dart';
import 'BaseHttpModel.dart';
import 'UrlPath.dart';
import 'DataHelper.dart';
class HttpManager {
static HttpManager _instance = HttpManager._internal();
Dio _dio;
static const CODE_SUCCESS = 200;
static const CODE_TIME_OUT = -1;
static const CONNECT_TIMEOUT = 15000;
factory HttpManager() => _instance;
///通用全局单例,第一次使用时初始化
HttpManager._internal({String baseUrl}) {
if (null == _dio) {
_dio = new Dio(new BaseOptions(
baseUrl: UrlPath.baseUrl, connectTimeout: CONNECT_TIMEOUT));
_dio.interceptors.add(new DioLogInterceptor());
_dio.interceptors.add(new ResponseInterceptors());
baseUrl: UrlPath.baseUrl, connectTimeout: 15000));
}
}
......@@ -53,84 +43,25 @@ class HttpManager {
return this;
}
///通用的GET请求
get(api, {params, withLoading = true}) async {
if (withLoading) {
Loading.show();
request(String url,
{parameters,
method = 'GET',
Function(BaseHttpModel t, String errorMsg) onResult}) async {
parameters = parameters ?? {};
if(onResult==null){
return;
}
Response response;
// params["platform"] = "android";
// params["system"] = "1.0.0";
// params["channel"] = "App";
// params["time"] = new DateTime.now().millisecondsSinceEpoch.toString();
// params["sign"] = DataHelper.encryptParams(params);
try {
response = await _dio.get(api, queryParameters: params);
if (withLoading) {
Loading.dismiss();
Response response = await _dio.request(url,
queryParameters: parameters, options: new Options(method: method));
BaseHttpModel httpModel = BaseHttpModel.fromJson(response.data);
if (httpModel.isSuccess() == true) {
onResult(httpModel, null);
}else{
onResult(httpModel, httpModel.errorMsg());
}
} on DioError catch (e) {
if (withLoading) {
Loading.dismiss();
}
return resultError(e);
}
if (response.data is DioError) {
return resultError(response.data['code']);
}
return response.data;
}
///通用的POST请求
post(api, {params, withLoading = true}) async {
if (withLoading) {
Loading.show();
}
Response response;
// params["platform"] = "android";
// params["system"] = "1.0.0";
// params["channel"] = "App";
// params["time"] = new DateTime.now().millisecondsSinceEpoch.toString();
// params["sign"] = DataHelper.encryptParams(params);
try {
response = await _dio.post(api, data: params);
if (withLoading) {
Loading.dismiss();
}
} on DioError catch (e) {
if (withLoading) {
Loading.dismiss();
}
return resultError(e);
}
if (response.data is DioError) {
return resultError(response.data['code']);
}
return response.data;
}
}
ResultData resultError(DioError e) {
Response errorResponse;
if (e.response != null) {
errorResponse = e.response;
} else {
errorResponse = new Response(statusCode: 666);
onResult(null, e.message);
}
if (e.type == DioErrorType.connectTimeout ||
e.type == DioErrorType.receiveTimeout) {
errorResponse.statusCode = Code.NETWORK_TIMEOUT;
}
return new ResultData(
null, false,-1,errorResponse.statusMessage);
}
import 'package:flutter_easyloading/flutter_easyloading.dart';
class Loading {
static show() {
EasyLoading.show();
}
static dismiss() {
EasyLoading.dismiss();
}
}
import 'package:dio/dio.dart';
import 'ResultData.dart';
/// 数据初步处理
class ResponseInterceptors extends InterceptorsWrapper {
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
RequestOptions option = response.requestOptions;
try {
if (option.contentType != null && option.contentType.contains("text")) {
response.data = ResultData(response.data, true, 0,'');
handler.next(response);
}
///一般只需要处理200的情况,300、400、500保留错误信息,外层为http协议定义的响应码
if (response.statusCode == 200 || response.statusCode == 201) {
///内层需要根据公司实际返回结构解析,一般会有code,data,msg字段
int code = response.data["code"];
String msg = response.data["msg"];
if (code == 0) {
response.data = ResultData(response.data, true, code ,msg);
handler.next(response);
} else {
response.data = ResultData(response.data, false, code, msg);
handler.next(response);
}
}
} catch (e) {
print("ResponseError====" + e.toString() + "****" + option.path);
response.data = ResultData(response.data, false, -1, '网络有误');
handler.next(response);
}
response.data = ResultData(response.data, false, -1,'网络有误');
handler.next(response);
}
}
class ResultData {
var data;
bool isSuccess;
int code;
var msg;
ResultData(this.data, this.isSuccess, this.code, this.msg);
}
......@@ -37,15 +37,19 @@ dependencies:
http: 0.13.3
mqtt_client: ^9.3.2
flutter_easyrefresh: ^2.2.1 #下拉刷新
json_annotation: ^4.0.1 #json解析
json_annotation: ^3.1.1 #json解析
flutter_easyloading: ^3.0.0 #简单的加载loading
dio: ^4.0.0 #网络库
convert: ^3.0.1 #转码器
pull_to_refresh: ^2.0.0
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^1.0.0
json_serializable: ^3.5.1
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment