You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.8 KiB
120 lines
3.8 KiB
import 'package:flutter/material.dart';
|
|
|
|
import 'package:recook/constants/header.dart';
|
|
|
|
class CustomBubblePopPainter extends CustomPainter {
|
|
final double startX;
|
|
final String text;
|
|
CustomBubblePopPainter(this.startX, {this.text = ""});
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
Paint p = new Paint();
|
|
p.color = Colors.white; //画笔颜色
|
|
// p.color = Colors.red;
|
|
p.strokeWidth = 1;
|
|
p.isAntiAlias = true; //是否抗锯齿
|
|
p.style = PaintingStyle.fill; //画笔样式:填充
|
|
// canvas.drawCircle(size.center(Offset(0.0, 0.0)), size.width / 2, p);
|
|
Path path = Path()..moveTo(0, 10);
|
|
// 左上角
|
|
Rect rectLeftTop = Rect.fromCircle(center: Offset(5, 10), radius: 5);
|
|
path.arcTo(rectLeftTop, 3.14, 3.14 * 0.5, false);
|
|
//
|
|
path.lineTo(startX - 5, 5);
|
|
path.lineTo(startX, 0);
|
|
path.lineTo(startX + 5, 5);
|
|
path.lineTo(size.width - 5, 5);
|
|
// 右上角
|
|
Rect rectRightTop =
|
|
Rect.fromCircle(center: Offset(size.width - 5, 10), radius: 5);
|
|
path.arcTo(rectRightTop, 3.14 * 1, 3.14 * 1, false);
|
|
path.lineTo(size.width, size.height - 5);
|
|
// 右下角
|
|
Rect rectRightBottom = Rect.fromCircle(
|
|
center: Offset(size.width - 5, size.height - 5), radius: 5);
|
|
path.arcTo(rectRightBottom, 3.14 * 1.5, 3.14 * 1, false);
|
|
path.lineTo(5, size.height);
|
|
// 左下角
|
|
Rect rectLeftBottom =
|
|
Rect.fromCircle(center: Offset(5, size.height - 5), radius: 5);
|
|
path.arcTo(rectLeftBottom, 3.14 * .5, 3.14 * .5, false);
|
|
canvas.drawPath(path, p);
|
|
|
|
TextPainter textPainter = TextPainter(
|
|
textAlign: TextAlign.start,
|
|
maxLines: 2,
|
|
textDirection: TextDirection.ltr);
|
|
textPainter.text = TextSpan(children: [
|
|
TextSpan(text: text, style: TextStyle(color: Colors.black, fontSize: 10)),
|
|
]);
|
|
textPainter.layout(
|
|
maxWidth: size.width,
|
|
);
|
|
textPainter.paint(canvas, Offset(10, 8));
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(CustomBubblePopPainter oldDelegate) => true;
|
|
}
|
|
|
|
class CustomBubbleArrowPopPainter extends CustomPainter {
|
|
final double startX;
|
|
CustomBubbleArrowPopPainter(
|
|
this.startX,
|
|
);
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
Paint p = new Paint();
|
|
p.color = Colors.white; //画笔颜色
|
|
// p.color = Colors.red;
|
|
p.strokeWidth = 1;
|
|
p.isAntiAlias = true; //是否抗锯齿
|
|
p.style = PaintingStyle.fill; //画笔样式:填充
|
|
// canvas.drawCircle(size.center(Offset(0.0, 0.0)), size.width / 2, p);
|
|
Path path = Path()..moveTo(startX, 0);
|
|
path.lineTo(startX + 5, 10);
|
|
path.lineTo(startX - 5, 10);
|
|
path.lineTo(startX, 0);
|
|
canvas.drawPath(path, p);
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(CustomBubbleArrowPopPainter oldDelegate) => true;
|
|
}
|
|
|
|
class CustomBubbleWidget extends StatefulWidget {
|
|
final double arrowLeftPadding;
|
|
final Widget child;
|
|
CustomBubbleWidget({Key key, this.arrowLeftPadding = 10, this.child})
|
|
: super(key: key);
|
|
|
|
@override
|
|
_CustomBubbleWidgetState createState() => _CustomBubbleWidgetState();
|
|
}
|
|
|
|
class _CustomBubbleWidgetState extends State<CustomBubbleWidget> {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
CustomPaint(
|
|
painter: CustomBubbleArrowPopPainter(
|
|
widget.arrowLeftPadding,
|
|
),
|
|
size: Size(widget.arrowLeftPadding + 10, 10),
|
|
),
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
color: Colors.white, borderRadius: BorderRadius.circular(10)),
|
|
width: double.infinity,
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: rSize(10), vertical: 10 * 2.h),
|
|
child: widget.child == null ? Container() : widget.child)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|