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),
),
);
}
效果图: