Flutter+WebRTC开发点对点加密即时通讯APP--好友列表界面实现

Flutter+WebRTC开发点对点加密即时通讯APP--好友列表界面实现

开篇

基于Flutter+WebRTC,开发一款点对点加密、跨端、即时通讯APP,实现文字、音视频通话聊天,同时支持图片、短视频等文件传输功能,计划支持Windows、Android平台。我准备将自己的学习和实践过程记录下来,同时分享给大家,欢迎大家一起研讨交流。这个工程是利用自己的业余时间来实现的,不定时更新。本篇文章实现APP的好友列表界面。

主体布局

好友列表我们计划使用三段式布局,从上到下依次放置标题部分,好友列表部分,底部按钮功能区三部分。底部按钮功能区前边已经实现了,这里就不需要再次绘制。首先定义一个FriendsList组件,最外层放置SafeArea组件,防止屏幕边缘显示出现问题,然后使用竖向布局Column,在其中预留两个子组件,分别放置顶部标题和好友列表。

dart 复制代码
class FriendsList extends StatelessWidget {
  const FriendsList({super.key});

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Column(
        children: [
          Expanded(
            top()
          ),
          Expanded(
            friendslist()
          ),
        ],
      ),
    );
  }
}

顶部标题部分

顶部标题部分我们简单的放置"chat"文字和搜索按钮,Row组件横向布局放置我们的Text和Button。"chat"文字我们稍微实现点阴影效果,可以通过设置Text的TextStyle中的shadows属性来设置。搜索按钮我们使用Container组件来包裹,可以在Container中的BoxDecoration属性中设置背景颜色和圆角,这里我们设置为我们的主题颜色,粉色,

dart 复制代码
Row(
  children: [
    Expanded(
      child: Container(
        alignment: Alignment.centerLeft,
        padding: const EdgeInsets.fromLTRB(40, 0, 0, 0),
        child: const Text(
          "Chat",
          style: TextStyle(
            fontSize: 30,
            fontWeight: FontWeight.bold,
            shadows: [
              Shadow(
                offset: Offset(2.0, 2.0),
                blurRadius: 5.0,
                color: Color.fromARGB(255, 189, 188, 188),
              ),
            ],
          ),
        ),
      ),
    ),
    Container(
      height: 50,
      width: 48,
      decoration: BoxDecoration(
        color: const Color.fromARGB(255, 255, 244, 246),
        borderRadius: BorderRadius.circular(10),
      ),
      child: IconButton(
        onPressed: () {},
        icon: const Icon(
          Icons.search,
          size: 20,
          color: Color.fromARGB(255, 238, 156, 167),
        ),
      ),
    ),
    const SizedBox(
      width: 40,
    )
  ],
),

好友列表部分

现在我们来实现一下好友列表部分,因为好友上线是一个动态的过程,不确定哪个时间就会有好友上线,所以,这里使用ValueNotifier来监听好友上线情况,动态更新好友展示页面。首先要定义一个List<Map>类型的ValueNotifier,用来存放我们的好友信息。外层使用Container来进行包裹,框定一个区域来放置好友列表,同时使用灰色边框来凸显区域。

dart 复制代码
ValueNotifier<List<Map>> friendlist = ValueNotifier<List<Map>>([]);

ValueListenableBuilder(
  builder: (BuildContext context, value, Widget? child) {
    return Container(
      alignment: Alignment.center,
      width: MediaQuery.of(context).size.width,
      decoration: BoxDecoration(
        border: Border.all(
          color: Colors.grey.withAlpha(40),
        ),
      ),
      child: ListView.builder(
        itemBuilder: (context, index) {
          return friendlistfunc(
            context,
            index,
          );
        },
        itemCount: friendlist.value.length,
      ),
    );
  },
  valueListenable: friendlist,
),

好友列表函数

我们定义friendlistfunc函数来实现列表中每个好友的展示。ListTile是一个很好有的列表组件,开箱即用,我们可以设置leading来展示好友头像,title显示好友昵称,subtitle显示上线时间,trailing展示新消息提醒。

好友头像我们使用CircleAvatar组件来实现,通过这个组件,可以很容易的实现圆心头像的展示,前边我的文章也有过展示,大家可以翻出来看看。

未读信息我们使用chatmessagesmapnoread来保存,每次渲染界面的时候都对chatmessagesmapnoread中保存的未读信息数进行判断,进而显示未读提醒。

我们还需要监听onTap事件,也就是点击好友事件,当点击某一个好友时,我们就进行页面跳转,跳转到对应的聊天界面,聊天界面ChatBubble我们后边会实现。

dart 复制代码
friendlistfunc(BuildContext context, int index) {
  return ListTile(
    contentPadding: const EdgeInsets.fromLTRB(25, 10, 10, 10),
    leading: CircleAvatar(
      //图片圆形剪裁
      radius: 25, //圆形大小
      backgroundColor: Colors.white, //背景颜色设置为白色
      backgroundImage: AssetImage(friendlist.value[index]['image']),
    ),
    title: Padding(
      padding: const EdgeInsets.fromLTRB(0, 0, 0, 4),
      child: Text(friendlist.value[index]['name']),
    ),
    onTap: () {
      currname = friendlist.value[index]['name'];
      chatmessagesmapnoread[currname] = 0;
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (BuildContext context) {
            return const ChatBubble();
          },
        ),
      );
    },
    subtitle: Text(
      DateTime.now().toString().substring(0, 19),
      style: TextStyle(
        fontSize: 10,
        color: Colors.grey.withAlpha(180),
      ),
    ),
    trailing: chatmessagesmapnoread[friendlist.value[index]['name']] == 0
        ? Container(
            width: 0.1,
            color: Colors.white,
          )
        : Container(
            width: 3,
            color: const Color.fromARGB(255, 176, 247, 83),
          ),
  );
}

效果图:

相关推荐
咔叽布吉8 分钟前
【前端学习笔记】ES6 新特性
前端·笔记·学习
推开世界的门41 分钟前
web 中 canvas 污染 以及解决方案
前端
星离~1 小时前
css—轮播图实现
前端·css
龙雨LongYu121 小时前
vue3+ts 我写了一个跟swagger.yml生成请求和响应实体(接口)
前端·vue.js·typescript
swiftlzk1 小时前
redmi 12c 刷机
android·数据库
Stanford_11062 小时前
关于IDE的相关知识之一【使用技巧】
前端·ide·windows·微信小程序·微信公众平台·twitter·微信开放平台
_志哥_2 小时前
web开发环境下启动HTTPS服务访问
前端·javascript·https
爱健身的小刘同学2 小时前
安装 electron 依赖报错
前端·javascript·electron
耶啵奶膘2 小时前
uniapp+vue2+uview2.0导航栏组件二次封装
前端·javascript·uni-app
布兰妮甜2 小时前
如何使用 Tailwind CSS 构建响应式网站:详细指南
前端·css·tailwind css