Flutter — 简单使用请求 Dio
flutter dio 网络请求 移动端
1.post 请求
import 'package:dio/dio.dart';
import 'dart:convert' as JSON;
void main() async{
// Future getData() {
// String url = "https://xxxxxxx";
// var map = {
// };
//
// print("开始请求数据");
// return Dio().post(url, data: map);
//
// }
// getData().then((responseBody){
// print(responseBody);
// });
post(String url,Map data){
return Dio().post(url, data: data,options: Options(headers:{"Content-Type":'application/json'}));
}
String url = "https://xxxxxxx";
var map = {
};
var res = await post(url, map);
print(res);
}
2.通过请求来的数据实现简单列表
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'dart:convert' as JSON;
void main()async{
post(String url,Map data){
return Dio().post(url, data: data,options: Options(headers:{"Content-Type":'application/json'}));
}
String url = "https://xxxxxx";
var map = {
};
var res = await post(url, map);
Map result = JSON.jsonDecode(res.toString());
runApp(MyApp(
result['content']
));
}
class MyApp extends StatelessWidget {
final List items;
MyApp(this.items);
@override
Widget build(BuildContext context) {
return MaterialApp(
title:'Title',
home:Scaffold(
appBar: AppBar(title:Text('Hello')),
body:ListView.builder(
itemCount: items.length,
itemBuilder: (context,index){
return Column(
children: <Widget>[
ListTile(title: Text(items[index]['title'])),
Image.network(
items[index]['homepageId'] + '?x-oss-process=style/w800',
width: 200,
height:100,
fit:BoxFit.cover,
// color:Colors.pink,
// colorBlendMode: BlendMode.modulate,
),
],
);
},
)
)
);
}
}
3.有状态无状态
statelessWidget
Stateless widgets 无状态控件是不可变的, 这意味着它们的属性不能改变 - 所有的值都是最终的. 如 app 入口 runApp 的 widget
使用时继承 StatelessWidget
statefullWidget
Stateful widgets 有状态控件。持有的状态可在 widget 生命周期中发生变化实现一个 stateful widget 至少需要两个类。
- 1.一个 StatefulWidget 类
- 2.一个 State 类。 StatefulWidget 类本身是不变的,但是 State 类在 widget 生命周期中始终存在,且可改变
实现方式:
- 1.自定义一个类继承自 statefulWidget
- 2.重写 createState()方法,为该 statefulWidget 创建一个 state 对象
- 3.自定义一个状态类继承自 State,重写 build()方法,根据需要的逻辑处理返回 widget,build 方法会在 view 状态改变时进行回调,重新渲染(自动响应式框架)
widget 更新
widget 只支持一帧,每一帧都会重新绘制 widget 实例,相当于一次绘制整个界面,widget 本身都不可变,想要可变就需要控制状态,无状态和有状态 widget 的核心特性是相同的。每一帧它们都会重新构建,不同之处在于 StatefulWidget 有一个 State 对象,它可以跨帧存储状态数据并恢复它。可交互就是有状态的,stateless 中可以包含 stateful。
下拉加载
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'dart:convert' as JSON;
void main() async {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: 'List Demo',
theme: ThemeData(
primarySwatch: Colors.blue
),
home:MyHomePage()
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int page = 1;
List cases;
bool loading = false;
@override
Widget build(BuildContext context) {
var length = cases?.length ?? 0;
return Scaffold(
body: ListView.builder(
itemBuilder: (context,index){
print('$index @@@');
if(index == length){
load();
return new Center(
child: new Container(
margin: const EdgeInsets.only(top: 8.0),
width: 32.0,
height: 32.0,
child: const CircularProgressIndicator(),
),
);
} else if (index > length) {
return null;
}
return Column(
children: <Widget>[
ListTile(title: Text(cases[index]['title'])),
Image.network(
cases[index]['homepageId'] + '?x-oss-process=style/w800',
)]);
}),
);
}
Future load() async {
if (loading) {
return null;
}
loading = true;
try {
var url = "https://admin.atjia.com//api_cms/front/busiContentCaseFront/queryByParmsPC";
var map = {
"export": false,
"orderBy": "ups desc,rank asc,modify_time desc",
"page": page,
"pageSize": 10,
"queryParamList": [
{
"field": "searchKey",
"type": "string",
"logic": "like",
"value": "",
"items": []
},
{
"field": "designerId",
"items": [],
"logic": "",
"type": "",
"value": ""
},
{
"field": "caseType",
"type": "string",
"logic": "=",
"value": "1",
"items": []
}
]
};
var res = await post(url, map);
Map result = JSON.jsonDecode(res.toString());
var content = result['content'];
setState(() {
page += 1;
if (content is List) {
if (cases == null) {
cases = <Map>[];
}
cases = [...cases,...content];
}
});
} finally {
loading = false;
}
}
post(String url, Map data) {
return Dio().post(url,
data: data,
options: Options(headers: {"Content-Type": 'application/json'}));
}
}
在构建 ListView 时有 4 中选择:
-
利用显示的自列表来构造 List
。此构造函数适合于具有少量子元素的列表视图,因为构造列表需要为可能显示在列表视图中的每个子元素执行工作,而不仅仅是那些实际可见的子元素。 -
ListView.builder 利用 IndexedWidgetBuilder 来按需构造。这个构造函数适合于具有大量(或无限)子视图的列表视图,因为构建器只对那些实际可见的子视图调用。
-
使用 ListView.separated 构造函数,采用两个 IndexedWidgetBuilder:itemBuilder 根据需要构建子项 separatorBuilder 类似地构建出现在子项之间的分隔符子项。此构造函数适用于具有固定数量的子控件的列表视图。
-
使用 ListView.custom 的 SliverChildDelegate 构造,它提供了定制子模型的其他方面的能力。 例如,SliverChildDelegate 可以控制用于估计实际上不可见的孩子的大小的算法。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: 'List Demo',
home:Scaffold(
body: new ListView.separated(
itemBuilder: (BuildContext context, int index) {
return new Text("text $index");
},
separatorBuilder: (BuildContext context, int index) {
return new Container(height: 1.0, color: Colors.red);
},
itemCount: 40),
)
);
}
}
加一个点击事件
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'dart:convert' as JSON;
void main() async {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: 'List Demo',
home:MyHomePage()
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int page = 1;
List cases;
bool loading = false;
@override
Widget build(BuildContext context) {
var length = cases?.length ?? 0;
return Scaffold(
body: ListView.builder(
itemBuilder: (context,index){
print('$index @@@');
if(index == length){
load();
return new Center(
child: new Container(
margin: const EdgeInsets.only(top: 8.0),
width: 32.0,
height: 32.0,
child: const CircularProgressIndicator(),
),
);
} else if (index > length) {
return null;
}
return Column(
children: <Widget>[
ListTile(
title: Text(cases[index]['title']),
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
return new AlertDialog(
title: new Text(
'测试',
style: new TextStyle(
color: Colors.black54,
fontSize: 18.0,
),
),
content: new Text('您选择的标题为:${cases[index]['title']}'),
);
},
);
}
),
Image.network(
cases[index]['homepageId'] + '?x-oss-process=style/w800',
)
],
);
}),
);
}
Future load() async {
if (loading) {
return null;
}
loading = true;
try {
var url = "https://admin.atjia.com//api_cms/front/busiContentCaseFront/queryByParmsPC";
var map = {
"export": false,
"orderBy": "ups desc,rank asc,modify_time desc",
"page": page,
"pageSize": 10,
"queryParamList": [
{
"field": "searchKey",
"type": "string",
"logic": "like",
"value": "",
"items": []
},
{
"field": "designerId",
"items": [],
"logic": "",
"type": "",
"value": ""
},
{
"field": "caseType",
"type": "string",
"logic": "=",
"value": "1",
"items": []
}
]
};
var res = await post(url, map);
Map result = JSON.jsonDecode(res.toString());
var content = result['content'];
setState(() {
page += 1;
if (content is List) {
if (cases == null) {
cases = <Map>[];
}
cases = [...cases,...content];
}
});
} finally {
loading = false;
}
}
post(String url, Map data) {
return Dio().post(url,
data: data,
options: Options(headers: {"Content-Type": 'application/json'}));
}
}