1.字典(Map)、JSON、模型相互转换
// Map =>相当于字典
final Map chat = {
'name' : 'zhangsan',
'message' : 'nihao',
};
// 字典转json
// Map转json
final chatJson = json.encode(chat);
print('json == $chatJson');
// json转字典
final Map newChat = json.decode(chatJson);
print('newChat Map == $newChat');
print('name == ${newChat['name']}');
// 检测数据类型
if (newChat is Map) {
print('newChat is Map == ${newChat is Map}');
}
// 字典转模型
Chat objectChat = Chat.fromJson(newChat);
print('objectChat == $objectChat');
print('objectChat.name == ${objectChat.name}');
print('objectChat.message == ${objectChat.message}');
打印结果
flutter: json == {"name":"zhangsan","message":"nihao"}
flutter: newChat Map == {name: zhangsan, message: nihao}
flutter: name == zhangsan
flutter: newChat is Map == true
flutter: objectChat == Instance of 'Chat'
flutter: objectChat.name == zhangsan
flutter: objectChat.message == nihao
模型数据
class Chat {
final String name;
final String message;
final String imageUrl;
//{内部表示非必须的}
Chat({this.name, this.message, this.imageUrl});
factory Chat.fromJson(Map json){
return Chat(
name: json['name'],
message: json['message'],
imageUrl: json['imageUrl'],
);
}
}
2.网络get请求数据
1.返回数据模型
{
"chat_list": [
{
"imageUrl": "https://randomuser.me/api/portraits/men/30.jpg",
"name": "Steven Moore",
"message": "头者交二成她须场增复信行米长铁工观。立表北团才重后温式九却想间计。界究间总识小领达论以身文大同节内身米。处声地育万必员现造周土在又个属心果。"
},
{
"imageUrl": "https://randomuser.me/api/portraits/men/60.jpg",
"name": "Scott Harris",
"message": "元经西响出难且住育共你具场研律连风任。社面基光无外程而属温据着白。记影很又下情特老正基今去几日入。农想林被间斯交候派还放被些证。维已写很场备为年议林任十我打起年。往之细后出建明影得构多你称拉。"
},
{
"imageUrl": "https://randomuser.me/api/portraits/men/53.jpg",
"name": "Matthew Robinson",
"message": "始局化儿定原老管信低实想形越日。复论己带品影位中来百次群想响划算。取儿导平院质确志除正选断设民派。具明实深把容别重小完受国有定方现该必。"
}
]
}
2.发起GET请求
// async 异步
// await 等待后面的结果
// async和await配套使用
// Future 可选类型 有可能有值,也可能为空或者错误
// Future 两种状态 1.正在执行 2.结束
// 结束有两种情况,成功或者失败
Future<List<Chat>> getChatData() async {
final response = await http.get('http://rap2api.taobao.org/app/mock/224518/api/chat/list');
print('statusCode == ${response.statusCode}');
print('body == ${response.body}');
if (response.statusCode == 200) {
// 获取响应数据,并且转换成Map
// 根据数据结构responseMap是Map
final responseBodyMap = json.decode(response.body);
final responseBodyList = responseBodyMap['chat_list'];
// map 遍历 相当于for 字典转模型并且放在数组里
// List<Chat> chatList = responseBodyMap['chat_list'].map<Chat>(
// (item) {
// print('item == $item');
// return Chat.fromJson(item);
// }
// ).toList();
// print(chatList);
// map 遍历 相当于for
// 字典转模型并且放在数组里
List<Chat> chatList = responseBodyMap['chat_list']
.map<Chat>((item) => Chat.fromJson(item))
.toList();
print(chatList);
return chatList;
} else {
// 抛出异常
throw Exception('statusCode:${response.statusCode}');
}
}
3.调用请求
// 调用 datas就是返回的 模型数组
// 由于是异步的,所以,在then里面获取数据
getChatData().then(
(data){
print('datas == $data');
});
3. FutureBuilder 小部件渲染异步请求,ListTile渲染列表
import 'package:flutter/material.dart';
// http 请求package as http别名
import 'package:http/http.dart' as http;
// json map 转换 package
import 'dart:convert';
import 'chat.dart';
class ChatPage extends StatefulWidget {
@override
_ChatPageState createState() => _ChatPageState();
}
// 创建Item 返回类型要一致 PopupMenuItem<String>
PopupMenuItem<String> _buildItem(String imageAss, String title) {
return PopupMenuItem(
child: Row(
children: <Widget>[
Image(image: AssetImage(imageAss), width: 20,),
// 间距
Container(width: 20,),
Text(title, style: TextStyle(color: Colors.white),),
],
),
);
}
// 回调函数
List<PopupMenuItem<String>> _buildPopupMenuItem(BuildContext context) {
return<PopupMenuItem<String>>[
_buildItem('images/发起群聊.png', '发起群聊'),
_buildItem('images/添加朋友.png', '添加朋友'),
_buildItem('images/扫一扫1.png', '扫一扫'),
_buildItem('images/收付款.png', '收付款'),
];
}
//void Function(T value);
void _onSelectedFor(String item) {
print('item == $item');
}
class _ChatPageState extends State<ChatPage> {
@override
void initState(){
super.initState();
// 请求数据
// getChatData().then(
// (data){
// print('datas == $data');
// });
print('getDatas');
}
// async 异步
// await 等待后面的结果
// async和await配套使用
// Future 可选类型 有可能有值,也可能为空或者错误
// Future 两种状态 1.正在执行 2.结束
// 结束有两种情况,成功或者失败
Future<List<Chat>> getChatData() async {
final response = await http.get('http://rap2api.taobao.org/app/mock/224518/api/chat/list');
print('statusCode == ${response.statusCode}');
print('body == ${response.body}');
if (response.statusCode == 200) {
// 获取响应数据,并且转换成Map
// 根据数据结构responseMap是Map
final responseBodyMap = json.decode(response.body);
final responseBodyList = responseBodyMap['chat_list'];
// map 遍历 相当于for
// List<Chat> chatList = responseBodyMap['chat_list'].map<Chat>(
// (item) {
// print('item == $item');
// return Chat.fromJson(item);
// }
// ).toList();
// print(chatList);
// map 遍历 相当于for
List<Chat> chatList = responseBodyMap['chat_list']
.map<Chat>((item) => Chat.fromJson(item))
.toList();
print(chatList);
return chatList;
// if (responseBodyMap is Map) {
// print('responseBodyMap == $responseBodyMap');
// }
// if (responseBodyList is List) {
// print('responseBodyList == $responseBodyList');
// }
} else {
// 抛出异常
throw Exception('statusCode:${response.statusCode}');
}
}
Color themColor = Color.fromRGBO(220, 220, 220, 1.0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// 安卓标题居中
centerTitle: true,
backgroundColor: themColor,
// 去掉导航栏和controller之间的线
elevation: 0.0,
title: Text('微信', style: TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500,),),
actions: <Widget>[
Container(
padding: EdgeInsets.only(left: 10, right: 10,),
child:PopupMenuButton(
onSelected: _onSelectedFor,
offset: Offset(0, 60.0),
padding: EdgeInsets.only(right: 100,),
child: Image(image: AssetImage('images/圆加.png'), width: 30, ),
itemBuilder: _buildPopupMenuItem,
),
),
],
),
// FutureBuilder 异步请求小部件
// 比较简单的可以这样,但是,每次进来都会请求数据
body: FutureBuilder(
future: getChatData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
print('snapshot.data == ${snapshot.data}');
print('snapshot.connectionState == ${snapshot.connectionState}');
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: Text('Loading...'),) ;
} else {
return ListView(
children: snapshot.data.map<Widget>(
(item) {
return Column(
children: <Widget>[
Container(
child: ListTile(
title: Text(item.name, overflow: TextOverflow.ellipsis,),
subtitle: Container(height: 20, width: 20, child: Text(item.message, overflow: TextOverflow.ellipsis,),),
leading: CircleAvatar(
backgroundImage: NetworkImage(item.imageUrl),
backgroundColor: Colors.red,
),
),
),
Container(
margin: EdgeInsets.only(left: 60),
width: MediaQuery.of(context).size.width - 60,
height: 0.5,
color: Color.fromRGBO(223, 223, 223, 1.0),
),
],
);
}
).toList(),
);
}
},
),
);
}
}
网友评论