如果您想使用库完成此操作,您可以从 pub.dev 添加 bubble: ^1.1.9+1
(选择最新版本)包,并在 Bubble 中包装您的消息。
Bubble(
style: right ? styleMe : styleSomebody,
//Your message content child here...
)
这里right
是一个布尔值,用于告诉气泡位于右侧还是左侧,请编写您的逻辑代码,并在您的小部件内添加styleMe
和styleSomebody
样式属性,如下所示。根据您的主题更改样式。
double pixelRatio = MediaQuery.of(context).devicePixelRatio;
double px = 1 / pixelRatio;
BubbleStyle styleSomebody = BubbleStyle(
nip: BubbleNip.leftTop,
color: Colors.white,
elevation: 1 * px,
margin: BubbleEdges.only(top: 8.0, right: 50.0),
alignment: Alignment.topLeft,
);
BubbleStyle styleMe = BubbleStyle(
nip: BubbleNip.rightTop,
color: Colors.grey,
elevation: 1 * px,
margin: BubbleEdges.only(top: 8.0, left: 50.0),
alignment: Alignment.topRight,
);
大家好,我也在寻找一个聊天气泡形状的小部件,最终我自己制作了一个。 我是通过自定义Painter实现的,但我并不是很擅长。
import 'package:flutter/material.dart';
class ChatBubble extends CustomPainter {
final Color color;
final Alignment alignment;
ChatBubble({
@required this.color,
this.alignment,
});
var _radius = 10.0;
var _x = 10.0;
@override
void paint(Canvas canvas, Size size) {
if (alignment == Alignment.topRight) {
canvas.drawRRect(
RRect.fromLTRBAndCorners(
0,
0,
size.width - 8,
size.height,
bottomLeft: Radius.circular(_radius),
topRight: Radius.circular(_radius),
topLeft: Radius.circular(_radius),
),
Paint()
..color = this.color
..style = PaintingStyle.fill);
var path = new Path();
path.moveTo(size.width - _x, size.height - 20);
path.lineTo(size.width - _x, size.height);
path.lineTo(size.width, size.height);
canvas.clipPath(path);
canvas.drawRRect(
RRect.fromLTRBAndCorners(
size.width - _x,
0.0,
size.width,
size.height,
topRight: Radius.circular(_radius),
),
Paint()
..color = this.color
..style = PaintingStyle.fill);
} else {
canvas.drawRRect(
RRect.fromLTRBAndCorners(
_x,
0,
size.width,
size.height,
bottomRight: Radius.circular(_radius),
topRight: Radius.circular(_radius),
topLeft: Radius.circular(_radius),
),
Paint()
..color = this.color
..style = PaintingStyle.fill);
var path = new Path();
path.moveTo(0, size.height);
path.lineTo(_x, size.height);
path.lineTo(_x, size.height-20);
canvas.clipPath(path);
canvas.drawRRect(
RRect.fromLTRBAndCorners(
0,
0.0,
_x,
size.height,
topRight: Radius.circular(_radius),
),
Paint()
..color = this.color
..style = PaintingStyle.fill);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
复制并粘贴上面的代码到你的项目中。
Align(
alignment: alignment, //Change this to Alignment.topRight or Alignment.topLeft
child: CustomPaint(
painter: ChatBubble(color: Colors.blue, alignment: alignment),
child: Container(
margin: EdgeInsets.all(10),
child: Stack(
children: <Widget>[
TextView("Hello World"),
],
),
),
),
)
将此代码粘贴到需要显示ChatBubble Widget的位置。 我还在Bitbucket上传了这段代码 ChatBubble Widget。如果您有任何贡献,请随意。
ClipRect
创建的小部件称为MyChatBubbleRect
。现在,使用CustomPainter绘制一个三角形,让我们称之为MyChatBubbleTriangle
,当然要用与聊天气泡相同的颜色进行填充,但是您可以最初使用不同的颜色进行调试。现在我们有了两个小部件,我们可以将它们堆叠在一起,并使用Positioned小部件覆盖在MyChatBubbleTriangle
上方。像这样:Stack(
children : [
MyChatBubbleRect(), // Maybe decrease the width a bit
Positioned(
top: 0,
right: 0,
child: MyChatBubbleTriangle()
)
]
)
我认为你可以追求这个想法。很抱歉我没有提供正确的源代码。
最初的回答:
我认为您可以尝试这个想法。很抱歉,我无法提供正确的源代码。
CustomPainter
硬编码并使其工作。 - Shababb KarimChat Body
DecoratedBox(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(8.0),
),
child: Text("your message goes here"),
);
class ChatBubbleTriangle extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
var paint = Paint()..color = Colors.blue;
var path = Path();
path.lineTo(-10, 0);
path.lineTo(0, 10);
path.lineTo(10, 0);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
ChatBubbleTriangle
与Positioned()
小部件一起包装。最初的回答。