1、导入依赖
导入http包的依赖
这里的依赖版本可以参考以下地址
参考网址:packages-http
dependencies:
flutter:
sdk: flutter
http: ^0.12.2
2、json转实体类
我们要通过网络请求来获取响应到的json数据,通常情况下要将响应到的数据封装成一个 model 对象,前端通过获得这个 model 来获取到所需要的数据。
json转换为实体类,我们可以使用自动生成工具,日常开发中也是这样操作的,因为都是固定格式的代码,使用自动工具可以极大简化开发流程。
关于具体的json转换为实体类,可以参考这篇文章 flutter自动转换json为实体类
之后我们会得到两个dart文件,此处的文件以个人生成为准,我生成的文件如下,文件结构可参考以上链接
SellBean.dart
SellBean.g.dart
3、业务逻辑
整体业务逻辑如下
发起请求,收到响应,封装数据,获得数据,展示数据
这是一个动态展示的过程,我们可以用两种方式实现:
1.使用StatefulWidget
2.使用StatelessWidget + 状态管理
这里我们使用第一种简单的方式,日常工作中多使用第二种方式
4、编写 UI
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:secondapp/dao/SellBean.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: new AppBar(
centerTitle: true,
backgroundColor: Color(0xFFFFFFFF),
title: new Text(
'预售专场',
style: TextStyle(color: Colors.black, fontSize: 20.0),
),
),
body: Center(
//child: listView,
child: new SellWidget(),
),
),
);
}
}
class SellWidget extends StatefulWidget {
const SellWidget({
Key key,
});
@override
_SellWidgetState createState() => new _SellWidgetState();
}
class _SellWidgetState extends State<SellWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: new Test(
"Hello World"),
);
}
这套 UI 中我们定义了 SellWidget 这个 Widget,以实现动态处理,其中省略了大部分的控件代码,具体的项目代码在文章最后给出
5、请求响应方法
static List<BikeModel> resBikeModels;
Future<void> getdata() async {
Map mapjson = {
"version": "2.6.0",
"userGuid": "3**************************49",
"token": "91******************************d5",
"clientId": "a7****************************07",
"tabCityCode": "0517",
"cityGuid": null,
"action": "rent.merchant.fat.*****",
"shopId": "30543"
};
var url = Uri.parse('https:/*********.com/api');
var response = await http.post(
url,
body: json.encode(mapjson),
);
//print('Response status: ${response.headers}');
String data = utf8.decode(response.bodyBytes);
//var data = json.encode(resJson.jsonRes);
//print('Response body: ${data}');
SellBean sellBean = SellBean.fromJson(json.decode(data));
// String resMap = sellBean.data.bikeModels[0].description;
// List resMap =
// json.decode(response.body)["data"]["bikeModels"];
// //print(resMap);
//print(sellBean.data.bikeModels[0].pic);
}
代码包裹在以下类中
class _SellWidgetState extends State<SellWidget> {}
- 我们首先定义一个全局变量
List<BikeModel> resBikeModels
这里的全局变量根据自身的返回值类型来确定,我这里返回的是链表 - 我们的网络请求是异步操作,所以需要
async关键字 - 参数
mapjson是请求体, 参数url是请求地址,http.post会自动发起post请求,返回json数据 utf8.decode编码为 utf8 格式字符串,SellBean.fromJson将字符串编码为json格式并封装到实体类中- 注释的代码可以放开,通过打印相关数据检查响应是否正确,在VSCode控制台中,如果打印的数据过长,它会被截断
6、调用请求,渲染 UI
我们需要在页面加载时就发起异步请求,这就需要在 state 的生命周期中初始化数据,不同的生命周期可以执行不同的业务逻辑,生命周期非常重要,关于 state 生命周期可以参考 《flutter 实战》
class _SellWidgetState extends State<SellWidget> {
@override
void initState() {
super.initState();
print("这里执行了 initState 方法 ");
getdata();
}
static List<BikeModel> resBikeModels;
Future<void> getdata() async {
...
}
}
重写 initState() 方法, 调用 getdata()方法
当加载该页面时,会先执行 initState() 方法执行初始化,此时页面中没有数据,是一个空白页,当请求到数据并返回后,会重新刷新 UI
7、全部代码
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:secondapp/dao/SellBean.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: new AppBar(
centerTitle: true,
backgroundColor: Color(0xFFFFFFFF),
title: new Text(
'预售专场',
style: TextStyle(color: Colors.black, fontSize: 20.0),
),
),
body: Center(
//child: listView,
child: new SellWidget(),
),
),
);
}
}
class SellWidget extends StatefulWidget {
const SellWidget({
Key key,
});
@override
_SellWidgetState createState() => new _SellWidgetState();
}
class _SellWidgetState extends State<SellWidget> {
static List<BikeModel> resBikeModels;
@override
void initState() {
super.initState();
print(" Future<void> main() async {");
getdata();
}
Future<void> getdata() async {
Map mapjson = {
"version": "2.6.0",
"userGuid": "3**************************49",
"token": "91******************************d5",
"clientId": "a7****************************07",
"tabCityCode": "0517",
"cityGuid": null,
"action": "rent.merchant.fat.*****",
"shopId": "30543"
};
var url = Uri.parse('https:/*********.com/api');
var response = await http.post(
url,
body: json.encode(mapjson),
);
//print('Response status: ${response.headers}');
String data = utf8.decode(response.bodyBytes);
//var data = json.encode(resJson.jsonRes);
//print('Response body: ${data}');
SellBean sellBean = SellBean.fromJson(json.decode(data));
// String resMap = sellBean.data.bikeModels[0].description;
// List resMap =
// json.decode(response.body)["data"]["bikeModels"];
// //print(resMap);
print(sellBean.data.bikeModels[0].pic);
setState(() {
resBikeModels = sellBean.data.bikeModels;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: new ListView.builder(
itemBuilder: (BuildContext context, int index) {
BikeModel bike = resBikeModels[index];
var hlIterm = Row(children: <Widget>[
_leftImg(bike),
Expanded(child: _rightColumn(bike))
], crossAxisAlignment: CrossAxisAlignment.start);
return Column(
children: <Widget>[
hlIterm,
Divider(
height: 1,
color: Colors.grey,
)
],
);
},
itemCount: resBikeModels?.length ?? 0),
),
);
}
Widget _leftImg(BikeModel bikeModel) {
var img = new Image(
image: NetworkImage(bikeModel.pic),
width: 110.0,
height: 100.0,
);
return _pd(img, l: 3, t: 10, r: 5, b: 10);
}
Widget _pd(Widget w, {double l, double t, double r, double b}) {
return Padding(
padding: EdgeInsets.fromLTRB(l ?? 0, t ?? 0, r ?? 0, b ?? 0),
child: w,
);
}
Widget _pda(Widget w, double a) {
return Padding(
padding: EdgeInsets.all(a),
child: w,
);
}
Widget _rightColumn(BikeModel bikeModel) {
// 标题格式
var titleStyle = TextStyle(color: Color(0xFF333333), fontSize: 14.0);
// 描述格式
var tagStyle = TextStyle(color: Color(0xFF999999), fontSize: 12.0);
// 价格格式
var priceStyle = TextStyle(
color: Color(0xFFFF5000),
fontSize: 24.0,
fontWeight: FontWeight.w600,
);
var littlePriceStyle = TextStyle(
color: Color(0xFFFF5000),
fontSize: 14.0,
fontWeight: FontWeight.w600,
);
var title = new Text(
bikeModel.modelName,
style: titleStyle,
maxLines: 2,
overflow: TextOverflow.ellipsis,
);
var tag = new Text(
bikeModel.description,
style: tagStyle,
);
var price = new Text(
bikeModel.minPrice.toString(),
style: priceStyle,
);
var priceRight = new Text('起', style: littlePriceStyle);
var priceLeft = new Text('¥', style: littlePriceStyle);
var deposit = Container(
margin: EdgeInsets.only(left: 10),
//边框设置
decoration: new BoxDecoration(
//背景
color: Color(0xFFFF5000),
//设置四周圆角 角度
borderRadius: BorderRadius.all(Radius.circular(4.0)),
//设置四周边框
border: new Border.all(width: 1, color: Colors.red),
),
child: new Text(
'定金¥${bikeModel.deposit}',
style: TextStyle(color: Color(0xFFFFFFFF)),
));
var priceRow =
Row(crossAxisAlignment: CrossAxisAlignment.end, children: <Widget>[
priceLeft,
price,
priceRight,
deposit,
]);
return new Column(
children: <Widget>[
_pd(title, t: 10),
_pd(tag, t: 10),
_pd(priceRow, t: 30)
],
crossAxisAlignment: CrossAxisAlignment.start,
);
}
}
本文介绍了在Flutter中如何在页面初始化时加载HTTP网络请求的数据,包括导入依赖、JSON转实体类、业务逻辑、UI编写、请求响应方法的实现以及调用请求并渲染UI的详细步骤。使用http包进行网络请求,并通过json转换为模型对象,然后在UI中动态展示数据。
1035

被折叠的 条评论
为什么被折叠?



