前言:上节我们完成了通讯录的简单搭建,本节为大家完成聊天页面的布局
本节知识点:
1.创建假mock数据,仿造聊天消息接口
前往接口官网http://rap2.taobao.org,
新建仓库接口:wechat
新建接口:http://rap2api.taobao.org/app/mock/283622/api/chatlist
2.引入http库文件
http: 0.12.1
执行Pub get
import 'package:http/http.dart' as http;//网络请求
//使用
http.get('http://rap2api.taobao.org/app/mock/283622/api/chatlist');
3.创建导航栏按钮PopupMenuButton
,并实现点击下拉弹窗
appBar: AppBar(
title: Text('微信'),
backgroundColor: wechatThemeColor,
actions: [
Container(
padding: EdgeInsets.only(right: 10),
child: PopupMenuButton(
offset: Offset(0,40),
child: Image.asset('images/圆加.png',width: 20,height: 20,),
itemBuilder: (BuildContext context){
return [
popItemWidget('images/发起群聊.png','发起群聊'),
popItemWidget('images/添加朋友.png','添加朋友'),
popItemWidget('images/扫一扫1.png','扫一扫'),
popItemWidget('images/收付款.png','收付款'),
];
}),
),
],
),
单独拎出来的方法,创建PopupMenuItem
PopupMenuItem popItemWidget(String imageUrl ,String title){
return PopupMenuItem(child: Container(
child: Row(
children: [
SizedBox(width: 10,),
Image.asset(imageUrl,width: 20,height: 20,) ,
SizedBox(width: 20,),
Text(title,style: TextStyle(color: Colors.white),),
],
),
));
}
run
5.定义数据模型
class ChatModel{
final String imageUrl;
final String name;
final String message;
ChatModel({
this.imageUrl,this.name,this.message
});
//工厂构造方法
factory ChatModel.jsonFrom(Map map){
return ChatModel(name: map['name'],imageUrl: map['imageUrl'],message: map['message']);
}
}
5.获取数据GetDatas()
class _State extends State<ChatPage> {
//初始化数据
List<ChatModel> _chatListDatas = [];
//是否取消网络访问(针对网络超时)
bool _cancleConnect = false;
Future<List<ChatModel>> _getchatDatas() async{
_cancleConnect = false;
//获取json数据
final response = await http.get('http://rap2api.taobao.org/app/mock/283622/api/chatlist');
if(response.statusCode == 200){
//将json转Map数据
Map listDatas = json.decode(response.body);
//转为
List<ChatModel> chat_list = listDatas['chat_list'].map<ChatModel>((e){
return ChatModel.jsonFrom(e);
}).toList();
return chat_list;
}else{
throw Exception('抛出错误');
}
}
...
}
@override
void initState() {
super.initState();
//获取聊天数据
_getDatas().then((List<ChatModel> values){
if(_cancleConnect == false){
//更新数据
setState(() {
_chatListDatas = values;//重新渲染
});
}
}).catchError((e){
print(e.toString());
}).timeout(Duration(seconds: 1)).catchError((timeout){
//超时
_cancleConnect == true;
});
}
body: Container(
child: _chatListDatas.length ==0 ? Center(child: Text('正在加载...'),) : Container(
child: ListView.builder(itemCount: _chatListDatas.length, itemBuilder: (BuildContext context, int index){
return ListTile(
title: Text(_chatListDatas[index].name),
leading: Container(
width: 50,
height:50,
child: Image.network(_chatListDatas[index].imageUrl),
),
subtitle: Text(_chatListDatas[index].message,overflow: TextOverflow.ellipsis,),
);
}),
)
),
FutureBuilder 的使用,等价于上面的ListView
body: FutureBuilder(future: _getDatas(), builder: (BuildContext context, AsyncSnapshot snapshot){
if(snapshot.connectionState == ConnectionState.waiting){
return Center(
child: Text('加载中...'),
);
}
if(snapshot.connectionState == ConnectionState.done){
return ListView(
children: snapshot.data.map<Widget>((item){
return ListTile(
title: Text(item.name),
leading: Container(
width: 50,
height:50,
child: Image.network(item.imageUrl),
),
subtitle: Text(item.message,overflow: TextOverflow.ellipsis,),
);
}).toList(),
);
}
return Container();
}),
run
网友评论