美文网首页
第九章:Flutter之wechatDemo(聊天页面)

第九章:Flutter之wechatDemo(聊天页面)

作者: Mr姜饼 | 来源:发表于2021-05-19 17:05 被阅读0次

前言:上节我们完成了通讯录的简单搭建,本节为大家完成聊天页面的布局

本节知识点:

1.创建假mock数据,仿造聊天消息接口

前往接口官网http://rap2.taobao.org
新建仓库接口:wechat
新建接口:http://rap2api.taobao.org/app/mock/283622/api/chatlist

image.png
2.引入http库文件

http: 0.12.1
执行Pub get

image.png
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

33.png
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

34.png

相关文章

网友评论

      本文标题:第九章:Flutter之wechatDemo(聊天页面)

      本文链接:https://www.haomeiwen.com/subject/owgjjltx.html