Flutter聊天气泡插件chat_bubbles的使用
Flutter聊天气泡插件chat_bubbles的使用
插件信息
chat_bubbles
是一个Flutter插件,提供了类似于WhatsApp的聊天气泡组件。它支持多种类型的聊天气泡、音频聊天气泡和日期标签,易于使用和集成。
快速开始
添加依赖
在项目的 pubspec.yaml
文件中添加以下依赖:
dependencies:
chat_bubbles: ^1.7.0
导入包
然后在需要使用的Dart文件中导入插件:
import 'package:chat_bubbles/chat_bubbles.dart';
使用示例
iMessage风格的聊天气泡
BubbleSpecialThree(
text: 'Added iMessage shape bubbles',
color: Color(0xFF1B97F3),
tail: false,
textStyle: TextStyle(
color: Colors.white,
fontSize: 16
),
),
BubbleSpecialThree(
text: 'Please try and give some feedback on it!',
color: Color(0xFF1B97F3),
tail: true,
textStyle: TextStyle(
color: Colors.white,
fontSize: 16
),
),
BubbleSpecialThree(
text: 'Sure',
color: Color(0xFFE8E8EE),
tail: false,
isSender: false,
),
BubbleSpecialThree(
text: "I tried. It's awesome!!!",
color: Color(0xFFE8E8EE),
tail: false,
isSender: false,
),
BubbleSpecialThree(
text: "Thanks",
color: Color(0xFFE8E8EE),
tail: true,
isSender: false,
)
单个聊天气泡
BubbleSpecialOne(
text: 'Hi, How are you? ',
isSender: false,
color: Colors.purple.shade100,
textStyle: TextStyle(
fontSize: 20,
color: Colors.purple,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
),
)
音频聊天气泡
Duration duration = new Duration();
Duration position = new Duration();
bool isPlaying = false;
bool isLoading = false;
bool isPause = false;
BubbleNormalAudio(
color: Color(0xFFE8E8EE),
duration: duration.inSeconds.toDouble(),
position: position.inSeconds.toDouble(),
isPlaying: isPlaying,
isLoading: isLoading,
isPause: isPause,
onSeekChanged: _changeSeek,
onPlayPauseButtonClick: _playAudio,
sent: true,
)
图片聊天气泡
BubbleNormalImage(
id: 'id001',
image: _image(),
color: Colors.purpleAccent,
tail: true,
delivered: true,
)
日期标签
DateChip(
date: new DateTime(2021, 5, 7),
color: Color(0x558AD3D5),
)
消息栏
MessageBar(
onSend: (_) => print(_),
actions: [
InkWell(
child: Icon(
Icons.add,
color: Colors.black,
size: 24,
),
onTap: () {},
),
Padding(
padding: EdgeInsets.only(left: 8, right: 8),
child: InkWell(
child: Icon(
Icons.camera_alt,
color: Colors.green,
size: 24,
),
onTap: () {},
),
),
],
)
完整的聊天视图示例
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:chat_bubbles/chat_bubbles.dart';
import 'package:audioplayers/audioplayers.dart';
import "package:cached_network_image/cached_network_image.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'chat bubble example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'chat bubble example'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
MyHomePage({Key? key, required this.title}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
AudioPlayer audioPlayer = new AudioPlayer();
Duration? duration = new Duration();
Duration? position = new Duration();
bool isPlaying = false;
bool isLoading = false;
bool isPause = false;
@override
void initState() {
super.initState();
audioPlayer.onDurationChanged.listen((Duration d) {
setState(() {
duration = d;
isLoading = false;
});
});
audioPlayer.onPositionChanged.listen((Duration p) {
if (isPlaying) {
setState(() {
position = p;
});
}
});
audioPlayer.onPlayerComplete.listen((event) {
setState(() {
isPlaying = false;
duration = new Duration();
position = new Duration();
});
});
}
@override
Widget build(BuildContext context) {
final now = new DateTime.now();
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Stack(
children: [
SingleChildScrollView(
child: Column(
children: <Widget>[
BubbleNormalImage(
id: 'id001',
image: _image(),
color: Colors.purpleAccent,
tail: true,
delivered: true,
),
BubbleNormalAudio(
color: Color(0xFFE8E8EE),
duration:
duration == null ? 0.0 : duration!.inSeconds.toDouble(),
position:
position == null ? 0.0 : position!.inSeconds.toDouble(),
isPlaying: isPlaying,
isLoading: isLoading,
isPause: isPause,
onSeekChanged: _changeSeek,
onPlayPauseButtonClick: _playAudio,
sent: true,
),
BubbleNormal(
text: 'bubble normal with tail',
isSender: false,
color: Color(0xFF1B97F3),
tail: true,
textStyle: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
BubbleNormal(
text: 'bubble normal with tail',
isSender: true,
color: Color(0xFFE8E8EE),
tail: true,
sent: true,
),
DateChip(
date: new DateTime(now.year, now.month, now.day - 2),
),
BubbleNormal(
text: 'bubble normal without tail',
isSender: false,
color: Color(0xFF1B97F3),
tail: false,
textStyle: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
BubbleNormal(
text: 'bubble normal without tail',
color: Color(0xFFE8E8EE),
tail: false,
sent: true,
seen: true,
delivered: true,
),
BubbleSpecialOne(
text: 'bubble special one with tail',
isSender: false,
color: Color(0xFF1B97F3),
textStyle: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
DateChip(
date: new DateTime(now.year, now.month, now.day - 1),
),
BubbleSpecialOne(
text: 'bubble special one with tail',
color: Color(0xFFE8E8EE),
seen: true,
),
BubbleSpecialOne(
text: 'bubble special one without tail',
isSender: false,
tail: false,
color: Color(0xFF1B97F3),
textStyle: TextStyle(
fontSize: 20,
color: Colors.black,
),
),
BubbleSpecialOne(
text: 'bubble special one without tail',
tail: false,
color: Color(0xFFE8E8EE),
sent: true,
),
BubbleSpecialTwo(
text: 'bubble special tow with tail',
isSender: false,
color: Color(0xFF1B97F3),
textStyle: TextStyle(
fontSize: 20,
color: Colors.black,
),
),
DateChip(
date: now,
),
BubbleSpecialTwo(
text: 'bubble special tow with tail',
isSender: true,
color: Color(0xFFE8E8EE),
sent: true,
),
BubbleSpecialTwo(
text: 'bubble special tow without tail',
isSender: false,
tail: false,
color: Color(0xFF1B97F3),
textStyle: TextStyle(
fontSize: 20,
color: Colors.black,
),
),
BubbleSpecialTwo(
text: 'bubble special tow without tail',
tail: false,
color: Color(0xFFE8E8EE),
delivered: true,
),
BubbleSpecialThree(
text: 'bubble special three without tail',
color: Color(0xFF1B97F3),
tail: false,
textStyle: TextStyle(color: Colors.white, fontSize: 16),
),
BubbleSpecialThree(
text: 'bubble special three with tail',
color: Color(0xFF1B97F3),
tail: true,
textStyle: TextStyle(color: Colors.white, fontSize: 16),
),
BubbleSpecialThree(
text: "bubble special three without tail",
color: Color(0xFFE8E8EE),
tail: false,
isSender: false,
),
BubbleSpecialThree(
text: "bubble special three with tail",
color: Color(0xFFE8E8EE),
tail: true,
isSender: false,
),
SizedBox(
height: 100,
)
],
),
),
MessageBar(
onSend: (_) => print(_),
actions: [
InkWell(
child: Icon(
Icons.add,
color: Colors.black,
size: 24,
),
onTap: () {},
),
Padding(
padding: EdgeInsets.only(left: 8, right: 8),
child: InkWell(
child: Icon(
Icons.camera_alt,
color: Colors.green,
size: 24,
),
onTap: () {},
),
),
],
),
],
),
);
}
Widget _image() {
return Container(
constraints: BoxConstraints(
minHeight: 20.0,
minWidth: 20.0,
),
child: CachedNetworkImage(
imageUrl: 'https://i.ibb.co/JCyT1kT/Asset-1.png',
progressIndicatorBuilder: (context, url, downloadProgress) =>
CircularProgressIndicator(value: downloadProgress.progress),
errorWidget: (context, url, error) => const Icon(Icons.error),
),
);
}
void _changeSeek(double value) {
setState(() {
audioPlayer.seek(new Duration(seconds: value.toInt()));
});
}
void _playAudio() async {
final url = 'https://download.samplelib.com/mp3/sample-15s.mp3';
if (isPause) {
await audioPlayer.resume();
setState(() {
isPlaying = true;
isPause = false;
});
} else if (isPlaying) {
await audioPlayer.pause();
setState(() {
isPlaying = false;
isPause = true;
});
} else {
log('play: loading');
setState(() {
isLoading = true;
});
await audioPlayer.play(UrlSource(url));
log('play: loaded');
setState(() {
audioPlayer.getDuration().then(
(value) => setState(() {
log('init duration: $value');
duration = value;
isLoading = false;
}),
);
audioPlayer.getCurrentPosition().then(
(value) => setState(() {
log('init position: $value');
position = value;
}),
);
isPlaying = true;
});
}
}
}
问题反馈
如果您在使用过程中遇到任何问题,请随时通过 GitHub Issues 提交反馈。
希望这个插件能帮助您快速构建出漂亮的聊天界面!如果有更多需求或建议,欢迎提交Pull Request。
更多关于Flutter聊天气泡插件chat_bubbles的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter聊天气泡插件chat_bubbles的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用chat_bubbles
插件来创建聊天气泡的示例代码。这个插件可以帮助你轻松地在Flutter应用中实现聊天界面的气泡效果。
首先,确保你的Flutter项目已经配置好并运行正常。然后,按照以下步骤添加并使用chat_bubbles
插件。
1. 添加依赖
在你的pubspec.yaml
文件中添加chat_bubbles
依赖:
dependencies:
flutter:
sdk: flutter
chat_bubbles: ^最新版本号 # 请替换为实际的最新版本号
然后运行flutter pub get
来安装依赖。
2. 导入插件
在你的Flutter项目中,导入chat_bubbles
插件:
import 'package:chat_bubbles/chat_bubbles.dart';
3. 创建聊天气泡布局
接下来,你可以在你的UI中使用ChatBubble
组件来创建聊天气泡。以下是一个简单的示例,展示了如何创建一个包含多个聊天气泡的列表:
import 'package:flutter/material.dart';
import 'package:chat_bubbles/chat_bubbles.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Chat Bubbles Example'),
),
body: ChatBubbleScreen(),
),
);
}
}
class ChatBubbleScreen extends StatelessWidget {
final List<Map<String, dynamic>> messages = [
{
'sender': 'User1',
'text': 'Hello, how are you?',
'isMe': true,
},
{
'sender': 'User2',
'text': 'I\'m good, thanks! How about you?',
'isMe': false,
},
{
'sender': 'User1',
'text': 'I\'m doing well, thanks for asking!',
'isMe': true,
},
];
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: messages.length,
itemBuilder: (context, index) {
Map<String, dynamic> message = messages[index];
bool isMe = message['isMe'];
return Padding(
padding: const EdgeInsets.only(vertical: 8.0),
child: ChatBubble(
sender: message['sender'],
text: message['text'],
isMe: isMe,
tail: ChatBubbleTail(
color: isMe ? Colors.blue : Colors.grey,
),
showSenderName: true,
showTime: false,
time: '12:34', // 这里可以设置为实际的时间
alignment: isMe ? Alignment.topleft : Alignment.topright,
onBubblePressed: () {
// 点击气泡时的回调
print('Bubble pressed: ${message['text']}');
},
),
);
},
);
}
}
4. 运行应用
现在,你可以运行你的Flutter应用,并查看聊天气泡的效果。这个示例展示了如何创建一个简单的聊天界面,其中包含了发送者和接收者的消息,并且可以通过点击气泡来触发一个回调函数。
请注意,chat_bubbles
插件的具体API和用法可能会随着版本的更新而有所变化,因此请参考插件的官方文档以获取最新的使用方法和示例代码。