Skip to content

Commit 175b167

Browse files
FLUT-929221-[others][flutter]: Updated the sample and read me description
1 parent 0e85401 commit 175b167

File tree

3 files changed

+70
-69
lines changed

3 files changed

+70
-69
lines changed

README.md

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
1-
# custombordershapesformessages
1+
# How to design a custom border shape for messages in Flutter SfChat widget
22

3-
A new Flutter project.
3+
This repository contains a sample to implement the custom border shape for messages on a [Syncfusion Flutter Chat](https://help.syncfusion.com/flutter/chat/getting-started) widget.
44

5-
## Getting Started
5+
Please refer the KB through this [link](https://support.syncfusion.com/agent/kb/18701).
66

7-
This project is a starting point for a Flutter application.
7+
## Syncfusion widgets:
88

9-
A few resources to get you started if this is your first Flutter project:
9+
This project used the following Syncfusion widget(s):
10+
* [Chat](https://www.syncfusion.com/flutter-widgets/flutter-chat)
1011

11-
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
12-
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
12+
## Supported platforms
1313

14-
For help getting started with Flutter development, view the
15-
[online documentation](https://docs.flutter.dev/), which offers tutorials,
16-
samples, guidance on mobile development, and a full API reference.
14+
Refer to the following link to know about the supported platform - [Platforms](https://help.syncfusion.com/flutter/system-requirements#supported-platforms)
15+
16+
## Requirements to run the sample
17+
18+
Refer to the following link to know about system requirements - [System Requirements](https://help.syncfusion.com/flutter/system-requirements)
19+
20+
## How to run the sample
21+
22+
1. Clone the sample and open it in preferred IDE.
23+
2. Run the application.
24+
25+
*Note: If you download the sample using the "Download ZIP" option, right-click it, select Properties, and then select Unblock.*
26+
27+
## License
28+
29+
Syncfusion has no liability for any damage or consequence that may arise by using or viewing the samples. The samples are for demonstrative purposes, and if you choose to use or access the samples, you agree to not hold Syncfusion liable, in any form, for any damage that is related to use, for accessing, or viewing the samples. By accessing, viewing, or seeing the samples, you acknowledge and agree Syncfusion’s samples will not allow you seek injunctive relief in any form for any claim related to the sample. If you do not agree to this, do not view, access, utilize, or otherwise do anything with Syncfusion’s samples.

custombordershapesformessages.iml

Lines changed: 0 additions & 17 deletions
This file was deleted.

lib/main.dart

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,18 @@ class ChatSampleState extends State<ChatSample> {
2323

2424
@override
2525
void initState() {
26+
// Initialize the list of chat messages.
2627
_messages = <ChatMessage>[
2728
ChatMessage(
28-
text: 'Hi! How are you?',
29+
text: 'Hi! How are you?', // Outgoing message.
2930
time: DateTime.now(),
3031
author: const ChatAuthor(
3132
id: '8ob3-b720-g9s6-25s8',
3233
name: 'Outgoing user name',
3334
),
3435
),
3536
ChatMessage(
36-
text: 'Fine, how about you?',
37+
text: 'Fine, how about you?', // Incoming message.
3738
time: DateTime.now(),
3839
author: const ChatAuthor(
3940
id: 'a2c4-56h8-9x01-2a3d',
@@ -42,17 +43,15 @@ class ChatSampleState extends State<ChatSample> {
4243
),
4344
),
4445
ChatMessage(
45-
text:
46-
'I’ve been doing well. I’ve started working on a new project recently.',
46+
text: 'I’ve been doing well. I’ve started working on a new project recently.',
4747
time: DateTime.now(),
4848
author: const ChatAuthor(
4949
id: '8ob3-b720-g9s6-25s8',
5050
name: 'Outgoing user name',
5151
),
5252
),
5353
ChatMessage(
54-
text:
55-
'That sounds great! I’ve been exploring a few new frameworks myself.',
54+
text: 'That sounds great! I’ve been exploring a few new frameworks myself.',
5655
time: DateTime.now(),
5756
author: const ChatAuthor(
5857
id: 'a2c4-56h8-9x01-2a3d',
@@ -69,29 +68,28 @@ class ChatSampleState extends State<ChatSample> {
6968
return Padding(
7069
padding: const EdgeInsets.only(left: 80, right: 80, bottom: 20),
7170
child: SfChat(
72-
messages: _messages,
73-
outgoingUser: '8ob3-b720-g9s6-25s8',
71+
messages: _messages, // Setting the messages list.
72+
outgoingUser: '8ob3-b720-g9s6-25s8', // Outgoing user ID.
7473
incomingBubbleSettings: ChatBubbleSettings(
75-
showTimestamp: false,
76-
showUserName: false,
77-
textStyle: TextStyle(color: Colors.white),
78-
contentPadding:
79-
EdgeInsets.only(top: 15, bottom: 30, left: 30, right: 30),
80-
contentBackgroundColor: Colors.green[600],
81-
contentShape: CustomBorderShape(isOutgoing: false),
74+
showTimestamp: false,
75+
showUserName: false,
76+
textStyle: TextStyle(color: Colors.white),
77+
contentPadding: EdgeInsets.only(top: 15, bottom: 30, left: 30, right: 30), // Ensure sufficient space inside the bubble to accommodate the custom tail shape.
78+
contentBackgroundColor: Colors.green[600],
79+
contentShape: CustomBorderShape(isOutgoing: false), // Custom shape for incoming message bubble.
8280
),
8381
outgoingBubbleSettings: ChatBubbleSettings(
84-
showTimestamp: false,
85-
showUserName: false,
86-
showUserAvatar: false,
87-
textStyle: TextStyle(color: Colors.white),
88-
contentPadding:
89-
EdgeInsets.only(top: 15, bottom: 30, left: 30, right: 30),
90-
contentBackgroundColor: Colors.deepPurple[600],
91-
contentShape: CustomBorderShape(isOutgoing: true)),
82+
showTimestamp: false, // Disabling the timestamp for a cleaner look.
83+
showUserName: false, // Disabling the username for a cleaner look.
84+
showUserAvatar: false, // Disabling the avatar for a cleaner look.
85+
textStyle: TextStyle(color: Colors.white),
86+
contentPadding: EdgeInsets.only(top: 15, bottom: 30, left: 30, right: 30),
87+
contentBackgroundColor: Colors.deepPurple[600],
88+
contentShape: CustomBorderShape(isOutgoing: true), // Custom shape for outgoing message bubble.
89+
),
9290
composer: const ChatComposer(
9391
decoration: InputDecoration(
94-
hintText: 'Type a message',
92+
hintText: 'Type a message',
9593
),
9694
),
9795
),
@@ -106,26 +104,31 @@ class ChatSampleState extends State<ChatSample> {
106104
}
107105

108106
class CustomBorderShape extends ShapeBorder {
109-
final bool isOutgoing;
110-
final double borderRadius;
111-
final double tailHeight;
107+
final bool isOutgoing; // Flag to check if the message is outgoing or incoming.
108+
final double borderRadius; // Border radius for rounded corners.
109+
final double tailHeight; // Height of the message tail.
112110

113111
const CustomBorderShape({
114112
required this.isOutgoing,
115-
this.borderRadius = 30.0,
116-
this.tailHeight = 15.0,
113+
this.borderRadius = 30.0, // Default value for border radius.
114+
this.tailHeight = 15.0, // Default value for tail height.
117115
});
118116

119117
@override
120118
EdgeInsetsGeometry get dimensions => EdgeInsets.zero;
121119

122120
@override
123121
Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
122+
// Calculate the bottom of the bubble considering the tail height.
124123
final double bottom = rect.bottom - tailHeight;
125-
final double adjustedRadius =
126-
borderRadius.clamp(0, (rect.width / 3).clamp(0, rect.height / 3));
127-
final path = Path();
128-
124+
// Adjust the radius based on width/height for better aesthetics.
125+
final double adjustedRadius = borderRadius.clamp(0, (rect.width / 3).clamp(0, rect.height / 3));
126+
// Store left and right positions for reusability.
127+
final double left = rect.left;
128+
final double right = rect.right;
129+
final Path path = Path();
130+
131+
// Create a rounded rectangle path for the bubble.
129132
path.addRRect(
130133
RRect.fromLTRBAndCorners(
131134
rect.left,
@@ -139,23 +142,25 @@ class CustomBorderShape extends ShapeBorder {
139142
),
140143
);
141144

142-
final tailStartX =
143-
isOutgoing ? rect.right - adjustedRadius : rect.left + adjustedRadius;
144-
final tailEndX = isOutgoing
145-
? rect.right - adjustedRadius * 1.4
146-
: rect.left + adjustedRadius * 1.5;
145+
// Calculate the start and end positions of the tail based on message type (outgoing/incoming).
146+
final double tailStartX =
147+
isOutgoing ? right - adjustedRadius : left + adjustedRadius;
148+
final double tailEndX = isOutgoing
149+
? right - adjustedRadius * 1.4
150+
: left + adjustedRadius * 1.5;
147151

152+
// Create the tail using a quadratic bezier curve.
148153
path.moveTo(tailStartX, bottom);
149154
path.quadraticBezierTo(
150155
isOutgoing
151-
? rect.right - adjustedRadius * 1.2
152-
: rect.left + adjustedRadius * 1.2,
156+
? right - adjustedRadius * 1.2
157+
: left + adjustedRadius * 1.2,
153158
bottom + tailHeight * 0.5,
154159
tailStartX,
155160
bottom + tailHeight,
156161
);
157-
path.lineTo(tailEndX, bottom);
158-
path.close();
162+
path.lineTo(tailEndX, bottom);
163+
path.close();
159164

160165
return path;
161166
}

0 commit comments

Comments
 (0)