Skip to content

Commit 57e4046

Browse files
authored
replace your file with this
1 parent 8bd2b93 commit 57e4046

File tree

1 file changed

+264
-0
lines changed

1 file changed

+264
-0
lines changed
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
import 'package:gap/gap.dart';
2+
import 'package:flutter_screenutil/flutter_screenutil.dart';
3+
import 'package:flutter/material.dart';
4+
5+
///iMessage's chat bubble type
6+
///
7+
///chat bubble color can be customized using [color]
8+
///chat bubble tail can be customized using [tail]
9+
///chat bubble display message can be changed using [text]
10+
///[text] is the only required parameter
11+
///message sender can be changed using [isSender]
12+
///chat bubble [TextStyle] can be customized using [textStyle]
13+
14+
class BubbleSpecialThree extends StatelessWidget {
15+
final bool isSender;
16+
final String text;
17+
final String sendTime;
18+
final bool tail;
19+
final Color color;
20+
final TextAlign textAlign;
21+
22+
const BubbleSpecialThree({
23+
Key? key,
24+
this.isSender = true,
25+
required this.text,
26+
required this.sendTime,
27+
this.color = Colors.white70,
28+
this.tail = true,
29+
this.textAlign = TextAlign.left,
30+
}) : super(key: key);
31+
32+
///chat bubble builder method
33+
@override
34+
Widget build(BuildContext context) {
35+
return Align(
36+
alignment: isSender ? Alignment.topRight : Alignment.topLeft,
37+
child: Padding(
38+
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
39+
child: CustomPaint(
40+
painter: SpecialChatBubbleThree(
41+
color: color,
42+
alignment: isSender ? Alignment.topRight : Alignment.topLeft,
43+
tail: tail,
44+
),
45+
child: Container(
46+
constraints: BoxConstraints(
47+
maxWidth: MediaQuery.of(context).size.width * .7,
48+
),
49+
margin: isSender
50+
? const EdgeInsets.fromLTRB(7, 7, 17, 7)
51+
: const EdgeInsets.fromLTRB(17, 7, 7, 7),
52+
child: Stack(
53+
children: <Widget>[
54+
Padding(
55+
padding: const EdgeInsets.only(left: 4, right: 4),
56+
child: Column(
57+
crossAxisAlignment: CrossAxisAlignment.end,
58+
children: [
59+
Text(
60+
text,
61+
style: TextStyle(
62+
color: Colors.white,
63+
fontSize: 16.sp,
64+
),
65+
textAlign: textAlign,
66+
),
67+
Gap(3.h),
68+
Text(
69+
sendTime,
70+
textAlign: TextAlign.right,
71+
style: TextStyle(
72+
color: Colors.white,
73+
fontSize: 10.sp,
74+
),
75+
),
76+
],
77+
),
78+
),
79+
],
80+
),
81+
),
82+
),
83+
),
84+
);
85+
}
86+
}
87+
88+
///custom painter use to create the shape of the chat bubble
89+
///
90+
/// [color],[alignment] and [tail] can be changed
91+
92+
class SpecialChatBubbleThree extends CustomPainter {
93+
final Color color;
94+
final Alignment alignment;
95+
final bool tail;
96+
97+
SpecialChatBubbleThree({
98+
required this.color,
99+
required this.alignment,
100+
required this.tail,
101+
});
102+
103+
final double _radius = 10.0;
104+
105+
@override
106+
void paint(Canvas canvas, Size size) {
107+
var h = size.height;
108+
var w = size.width;
109+
if (alignment == Alignment.topRight) {
110+
if (tail) {
111+
var path = Path();
112+
113+
/// starting point
114+
path.moveTo(_radius * 2, 0);
115+
116+
/// top-left corner
117+
path.quadraticBezierTo(0, 0, 0, _radius * 1.5);
118+
119+
/// left line
120+
path.lineTo(0, h - _radius * 1.5);
121+
122+
/// bottom-left corner
123+
path.quadraticBezierTo(0, h, _radius * 2, h);
124+
125+
/// bottom line
126+
path.lineTo(w - _radius * 3, h);
127+
128+
/// bottom-right bubble curve
129+
path.quadraticBezierTo(
130+
w - _radius * 1.5, h, w - _radius * 1.5, h - _radius * 0.6);
131+
132+
/// bottom-right tail curve 1
133+
path.quadraticBezierTo(w - _radius * 1, h, w, h);
134+
135+
/// bottom-right tail curve 2
136+
path.quadraticBezierTo(
137+
w - _radius * 0.8, h, w - _radius, h - _radius * 1.5);
138+
139+
/// right line
140+
path.lineTo(w - _radius, _radius * 1.5);
141+
142+
/// top-right curve
143+
path.quadraticBezierTo(w - _radius, 0, w - _radius * 3, 0);
144+
145+
canvas.clipPath(path);
146+
canvas.drawRRect(
147+
RRect.fromLTRBR(0, 0, w, h, Radius.zero),
148+
Paint()
149+
..color = color
150+
..style = PaintingStyle.fill);
151+
} else {
152+
var path = Path();
153+
154+
/// starting point
155+
path.moveTo(_radius * 2, 0);
156+
157+
/// top-left corner
158+
path.quadraticBezierTo(0, 0, 0, _radius * 1.5);
159+
160+
/// left line
161+
path.lineTo(0, h - _radius * 1.5);
162+
163+
/// bottom-left corner
164+
path.quadraticBezierTo(0, h, _radius * 2, h);
165+
166+
/// bottom line
167+
path.lineTo(w - _radius * 3, h);
168+
169+
/// bottom-right curve
170+
path.quadraticBezierTo(w - _radius, h, w - _radius, h - _radius * 1.5);
171+
172+
/// right line
173+
path.lineTo(w - _radius, _radius * 1.5);
174+
175+
/// top-right curve
176+
path.quadraticBezierTo(w - _radius, 0, w - _radius * 3, 0);
177+
178+
canvas.clipPath(path);
179+
canvas.drawRRect(
180+
RRect.fromLTRBR(0, 0, w, h, Radius.zero),
181+
Paint()
182+
..color = color
183+
..style = PaintingStyle.fill);
184+
}
185+
} else {
186+
if (tail) {
187+
var path = Path();
188+
189+
/// starting point
190+
path.moveTo(_radius * 3, 0);
191+
192+
/// top-left corner
193+
path.quadraticBezierTo(_radius, 0, _radius, _radius * 1.5);
194+
195+
/// left line
196+
path.lineTo(_radius, h - _radius * 1.5);
197+
// bottom-right tail curve 1
198+
path.quadraticBezierTo(_radius * .8, h, 0, h);
199+
200+
/// bottom-right tail curve 2
201+
path.quadraticBezierTo(
202+
_radius * 1, h, _radius * 1.5, h - _radius * 0.6);
203+
204+
/// bottom-left bubble curve
205+
path.quadraticBezierTo(_radius * 1.5, h, _radius * 3, h);
206+
207+
/// bottom line
208+
path.lineTo(w - _radius * 2, h);
209+
210+
/// bottom-right curve
211+
path.quadraticBezierTo(w, h, w, h - _radius * 1.5);
212+
213+
/// right line
214+
path.lineTo(w, _radius * 1.5);
215+
216+
/// top-right curve
217+
path.quadraticBezierTo(w, 0, w - _radius * 2, 0);
218+
canvas.clipPath(path);
219+
canvas.drawRRect(
220+
RRect.fromLTRBR(0, 0, w, h, Radius.zero),
221+
Paint()
222+
..color = color
223+
..style = PaintingStyle.fill);
224+
} else {
225+
var path = Path();
226+
227+
/// starting point
228+
path.moveTo(_radius * 3, 0);
229+
230+
/// top-left corner
231+
path.quadraticBezierTo(_radius, 0, _radius, _radius * 1.5);
232+
233+
/// left line
234+
path.lineTo(_radius, h - _radius * 1.5);
235+
236+
/// bottom-left curve
237+
path.quadraticBezierTo(_radius, h, _radius * 3, h);
238+
239+
/// bottom line
240+
path.lineTo(w - _radius * 2, h);
241+
242+
/// bottom-right curve
243+
path.quadraticBezierTo(w, h, w, h - _radius * 1.5);
244+
245+
/// right line
246+
path.lineTo(w, _radius * 1.5);
247+
248+
/// top-right curve
249+
path.quadraticBezierTo(w, 0, w - _radius * 2, 0);
250+
canvas.clipPath(path);
251+
canvas.drawRRect(
252+
RRect.fromLTRBR(0, 0, w, h, Radius.zero),
253+
Paint()
254+
..color = color
255+
..style = PaintingStyle.fill);
256+
}
257+
}
258+
}
259+
260+
@override
261+
bool shouldRepaint(CustomPainter oldDelegate) {
262+
return true;
263+
}
264+
}

0 commit comments

Comments
 (0)