flutter Chat Messaging UI 实现一个男神使用的聊天气泡界面
我们日常上网交流都会用到聊天工具,与男神聊天的UI界面肯定要特别好看,常见的聊天工具的聊天界面都是气泡样子的,聊天界面虽然不是每个APP都需要,但是随着APP社交化,现在APP上加入聊天界面是很常见的。例如,QQ拥有多样丰富的聊天气泡,全方位满足年轻人标榜个性的需求。而微信只有默认的绿色气泡,朴实无华。对话气泡是漫画放置台词的一种表现手法,对话气泡通常是由线条画成的,气泡的样式会因对白内容而有所变化。我们就来实现一个简单的聊天气泡界面。
开始之前
在实现聊天气泡界面之前,我们要考虑一下怎么实现。首先要实现的就是一个聊天气泡,区分聊天双方填充不同颜色并且填充留白,接受者和发送者双方的聊天气泡要左右两边分别对齐。气泡大小要随着文字长短变化,文字需要实现自动换行。接下来我们就一步一步的来实现。
聊天列表实现
首先构建假的聊天内容,创建ChatBubbleList组件,用ListView来包裹我们的聊天气泡。我们创建名为ChatBubble的StatelessWidget气泡组件,结合起来就可以用列表样式显示聊天气泡。实际使用中并不能使用ListView组件,这里只是为了简单,实际中需要使用ListView.builder来动态生成气泡组件。ListView的实现是直接返回最简单的列表结构,粗糙没有修饰,它可以沿一个方向线性排布所有子组件,并且它也支持列表项懒加载。
class ChatBubbleList extends StatelessWidget {
const ChatBubbleList({super.key});
@override
Widget build(BuildContext context) {
return ListView(
children: const [
Padding(
padding: EdgeInsets.all(12),
),
.....
ChatBubble(
text: '。。。。。。!?',
send: false,
),
],
);
}
}
聊天气泡组件实现
我们创建名为ChatBubble的StatelessWidget气泡组件,使用DecoratedBox实现聊天气泡,气泡里面包裹text组件显示文字。使用圆形图片剪切组件CircleAvatar显示头像。头像文件放入images文件夹,并在pubspec.yaml文件中设置assets。DecoratedBox可以在其子组件绘制前(或后)绘制一些装饰(Decoration),如背景、边框、渐变等。可以设置background参数,在子组件之后绘制内容,即背景装饰。也可以设置参数foreground,在子组件之上绘制,即前景。
assets:
- images/
ChatBubble需要传入text,send两个参数,text就是要显示的文字,用send区分发送者和接受者。
const ChatBubble({
Key? key,
required this.text,
required this.send,
}) : super(key: key);
final String text; //要显示的文字
final bool send; //左右对齐
根据send来设置DecoratedBox的背景颜色,区分发送者和接受者。
decoration: BoxDecoration(
color: send //背景颜色
? Color.fromARGB(255, 164, 208, 238)
: Color.fromARGB(255, 153, 231, 169),
borderRadius: BorderRadius.circular(16),
),
外层使用Row组件来包裹头像CircleAvatar组件和气泡DecoratedBox组件,在DecoratedBox气泡组件中使用Padding组件填充文字四周,使文字能在气泡中有边距的显示。CircleAvatar是一个圆形组件,可以在其中添加背景颜色、背景图像或一些文本。
class ChatBubble extends StatelessWidget {
const ChatBubble({
Key? key,
required this.text,
required this.send,
}) : super(key: key);
final String text; //要显示的文字
final bool send; //左右对齐
@override
Widget build(BuildContext context) {
return Row(
children: [
CircleAvatar(
//图片圆形剪裁
radius: 30, //圆形大小
backgroundColor: Colors.white, //背景颜色设置为白色
backgroundImage: send
? const AssetImage(
"images/3.jpeg", //图片
)
: const AssetImage(
"images/1.jpg", //图片
),
),
DecoratedBox(
decoration: BoxDecoration(
color: send //背景颜色
? Color.fromARGB(255, 164, 208, 238)
: Color.fromARGB(255, 153, 231, 169),
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
text,
style: const TextStyle(
fontSize: 14, //字体大小
color: Color.fromARGB(255, 48, 14, 43),
),
),
),
)
],
);
}
}
效果图如下:
雏形出现了,但是所有气泡组件都在同一边显示,这显然不是我想要的。
聊天气泡组件左右对齐
设置Row组件的mainAxisAlignment参数实现左右对齐。在头像组件和气泡组件之间添加Padding组件,这样头像和气泡之间就会有一定距离,看起来更自然一些。
mainAxisAlignment: send ? MainAxisAlignment.start : MainAxisAlignment.end,
效果图如下:
气泡这样就左右分别对齐了,但是,女孩子的这部分好像有点不对,头像好像应该显示在右边、文字的后边才对。并且目前文字还不能自动换行,如果文字太长就会报错。
聊天文字自动换行
我们使用Padding嵌套在最外层,根据发送者或者接收者在两边留白。聊天气泡应在左侧或右侧包含一些填充,以防止它在文本换行时将屏幕铺满。若果文字太长并且没有换行,那么就会直接填充满了屏幕,看起来就不是很美观自然。
Padding(
padding: EdgeInsets.fromLTRB(
send ? 4.0 : 50.0,
2,
send ? 50.0 : 4.0,
2,
),
.....
接下来使用Row组件嵌套Flexible组件实现文字自动换行。Flexible组件可以使Row、Column、Flex等子组件在主轴方向有填充可用空间的能力,但是不强制子组件填充可用空间。Flexible组件作用于单个子项的布局。
class ChatBubble extends StatelessWidget {
const ChatBubble({
Key? key,
required this.text,
required this.send,
}) : super(key: key);
final String text; //要显示的文字
final bool send; //左右对齐
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.fromLTRB(
send ? 6.0 : 50.0,
2,
send ? 50.0 : 6.0,
2,
),
child: Row(
mainAxisAlignment:
send ? MainAxisAlignment.start : MainAxisAlignment.end,
children: [
Flexible(
child: CircleAvatar(
//图片圆形剪裁
radius: 25, //圆形大小
backgroundColor: Colors.white, //背景颜色设置为白色
backgroundImage: send
? const AssetImage(
"images/3.jpeg", //图片
)
: const AssetImage(
"images/1.jpg", //图片
),
),
),
const Padding(
padding: EdgeInsets.fromLTRB(2, 0, 2, 0),
),
Flexible(
child: DecoratedBox(
decoration: BoxDecoration(
color: send //背景颜色
? Color.fromARGB(255, 164, 208, 238)
: Color.fromARGB(255, 153, 231, 169),
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
text,
style: const TextStyle(
fontSize: 14, //字体大小
color: Color.fromARGB(255, 48, 14, 43),
),
),
),
),
),
],
),
);
}
}
效果图如下:
总结
我们简单的实现了一个聊天界面UI,可以显示头像,文字可以自动换行,发送者与接收者聊天气泡左右两边分别对齐,并且设置了不同的背景颜色。目前为止基本满足了一个社交App的基本要求。即时通讯在社交生活中扮演着重要的角色,从早期的文字聊天到图片音频的发送,演变到现如今的即时语音与视频传输,即时通讯软件得到了迅速的发展,QQ、微信等社交软件使用人数不断增加。即时通讯在办公领域的应用也极为广泛,例如钉钉会议等软件都具有聊天功能,即时通讯软件能够让企业中各项工作第一时间汇总,各部门工作人员可以轻松地相互交流工作。一个实际使用的聊天UI肯定需要更多的功能,我们后续开发的时候可以在此基础上进一步优化,添加更多需要的功能。