基于Flutter的仿微信聊天应用

前言

  作为当下风头正劲的跨端框架,flutter成为原生开发者和前端开发者争相试水的领域,笔者将通过一个仿微信聊天的应用,展现flutter的开发流程和相关工具链,旨在熟悉flutter的开发生态,同时也对自己的学习过程进行一个总结。笔者是web前端开发,相关涉及原生的地方难免有错漏之处,欢迎批评指正。项目代码库链接放在文末。

功能简介

  1. 聊天列表
    本应用支持用户直接点对点聊天,使用webSocket实现消息提醒与同步
    好友列表页:
    好友列表页
    在聊天列表展示所有好友,点击进入聊天详情,未读消息通过好友头像右上角小红点表示。
    聊天页:
    聊天页

  2. 搜索页
    用户可以通过搜索添加好友:
    搜索页

  3. 个人中心页
    该页面可以进行个人信息的修改,包括调整昵称,头像,修改密码等等,同时可以退出登录。
    个人中心页

工具链梳理

这里列举了本例中使用的几个关键第三方库,具体的使用细节在功能实现部分会有详解。

  1. 消息同步与收发
    项目中使用webSocket同server进行通信,我的服务器是用node写的,webSocket使用socket.io来实现(详见文末链接),socket.io官方最近也开发了基于dart的配套客户端库socket_io_client,其与服务端配合使用。由此可来实现消息收发和server端事件通知。
  2. 状态管理
  • 持久化状态管理
    持久化状态指的是用户名、登录态、头像等等持久化的状态,用户退出app之后,不用重新登录应用,因为登录态已经保存在本地,这里使用的是一个轻量化的包shared_preferences,将持久化的状态通过写文件的方式保存在本地,每次应用启动的时候读取该文件,恢复用户状态。
  • 非持久化状态
    这里使用社区广泛使用的库provider来进行非持久化的状态管理,非持久化缓存指的是控制app展示的相关状态,例如用户列表、消息阅读态以及依赖接口的各种状态等等。笔者之前也有一篇博文对provider进行了介绍Flutter Provider使用指南
  1. 网络请求
    这里使用dio进行网络请求,进行了简单的封装
  2. 其他
  • 手机桌面消息通知小红点通过flutter_app_badger包来实现,效果如下:
    小红点

  • 修改用户头像时,获取本地相册或调用照相机,使用image_picker库来实现,图片的裁剪通过image_cropper库来实现

  • 网络图片缓存,使用cached_network_image来完成,避免使用图片时反复调用http服务

功能实现

  1. 应用初始化
    在打开app时,首先要进行初始化,请求相关接口,恢复持久化状态等。在main.dart文件的开头,进行如下操作:

为了避免文章充斥着大段具体业务代码影响阅读体验,本文的代码部分只会列举核心内容,部分常见逻辑和样式内容会省略,完整代码详见项目仓库

import 'global.dart';
...

//  在运行runApp,之间,运行global中的初始化操作
void main() => Global.init().then((e) => runApp(MyApp(info: e)));

接下来我们查看global.dart文件

library global;

import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
...
//  篇幅关系,省略部分包引用

// 为了避免单文件过大,这里使用part将文件拆分
part './model/User.dart';
part './model/FriendInfo.dart';
part './model/Message.dart';

//  定义Profile,其为持久化存储的类
class Profile {
  String user = '';
  bool isLogin = false;
  //  好友申请列表
  List friendRequest = [];
  //  头像
  String avatar = '';
  //  昵称
  String nickName = '';
  //  好友列表
  List friendsList = [];

  Profile();

  // 定义fromJson的构造方法,通过json还原Profile实例
  Profile.fromJson(Map json) {
    user = json['user'];
    isLogin = json['isLogin'];
    friendRequest = json['friendRequest'];
    avatar = json['avatar'];
    friendsList = json['friendsList'];
    nickName = json['nickName'];
  }
  //    定义toJson方法,将实例转化为json方便存储
  Map<String, dynamic> toJson() => {
    'user': user,
    'isLogin': isLogin,
    'friendRequest': friendRequest,
    'avatar': avatar,
    'friendsList': friendsList,
    'nickName': nickName
  };
}

//  定义全局类,实现初始化操作
class Global {
  static SharedPreferences _prefs;
  static Profile profile = Profile();

  static Future init() async {
    //  这里使用了shared_preferences这个库辅助持久化状态存储
    _prefs = await SharedPreferences.getInstance();

    String _profile = _prefs.getString('profile');
    Response message;
    if (_profile != null) {
      try {
        //  如果存在用户,则拉取聊天记录
        Map decodeContent = jsonDecode(_profile != null ? _profile : '');
        profile = Profile.fromJson(decodeContent);
        message = await Network.get('getAllMessage', { 'userName' : decodeContent['user'] });
      } catch (e) {
        print(e);
      }
    }
    String socketIODomain = 'http://testDomain';
    //  生成全局通用的socket实例,这个是消息收发和server与客户端通信的关键
    IO.Socket socket = IO.io(socketIODomain, <String, dynamic>{
      'transports': ['websocket'],
      'path': '/mySocket'
    });
    //  将socket实例和消息列表作为结果返回
    return {
      'messageArray': message != null ? message.data : [],
      'socketIO': socket
    };
  }
  //    定义静态方法,在需要的时候更新本地存储的数据
  static saveProfile() => _prefs.setString('profile', jsonEncode(profile.toJson()));
}
...

global.dart文件中定义了Profile类,这个类定义了用户的持久化信息,如头像、用户名、登录态等等,Profilet类还提供了将其json化和根据json数据还原Profile实例的方法。Global类中定义了整个应用的初始化方法,首先借助shared_preferences库,读取存储的json化的Profile数据,并将其还原,从而恢复用户状态。Global中还定义了saveProfile方法,供外部应用调用,以便更新本地存储的内容。在恢复本地状态后,init方法还请求了必须的接口,创建全局的socket实例,将这两者作为参数传递给main.dart中的runApp方法。global.dart内容过多,这里使用了part关键字进行内容拆分,UserModel等类的定义都拆分出去了,详见笔者的另一篇博文dart flutter 文件与库的引用导出

  1. 状态管理
    接下来我们回到main.dart中,观察MyApp类的实现:
class MyApp extends StatelessWidge
  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值