My chat bubble looks like this:
I want its timestamp to stick to the right side like the following:
Here is my code:
return Align(
alignment: alignment,
child: Bubble(
margin: BubbleEdges.only(
top: 10,
left: leftMargin,
right: rightMargin,
),
color: backgroundColor,
nip: bubbleNip,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
content,
const SizedBox(height: 5),
Text(timeFormat01(timestamp)),
],
),
),
);
How do I do that?
Using Row mainAxisAlignment: MainAxisAlignment.end
or Align alignment: Alignment.centerRight
leads to stretching all bubbles to max width.
Adding crossAxisAlignment: CrossAxisAlignment.end
to the Column will align all texts that are smaller than the timestamp text to the right side.
wrap your timestamp with Align
widget like this:
IntrinsicWidth(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
content,
SizedBox(height: 5),
Align(
alignment: Alignment.centerRight,
child: Text(timeFormat01(timestamp)),
),
],
),
)
You can achieve the desired effect by combining IntrinsicWidth
and Align
on your formatted Bubble
widget.
Output:
Source:
Read the comments for explanation.
void main() => runApp(
const MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(body: SafeArea(child: BubbleApp())),
),
);
class BubbleApp extends StatelessWidget {
const BubbleApp({super.key});
@override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.topRight,
/// [ConstrainedBox] is used to provide the maximum width
/// of any one chat bubble.
child: ConstrainedBox(
/// In this case, let's use 300.0, but
/// you can use MediaQuery.of(context) and a percentage.
constraints: const BoxConstraints(maxWidth: 300.0),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
/// Populate [children] however you manage your state.
children: const [
BubbleMessage(
message:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
" Aenean eleifend sed purus a tincidunt. Aenean varius erat "
" eget justo lacinia.",
),
BubbleMessage(message: "kdo!"),
],
),
),
);
}
}
/// This is the wrapper around your [Bubble] class.
class BubbleMessage extends StatelessWidget {
const BubbleMessage({super.key, required this.message});
final String message;
@override
Widget build(BuildContext context) {
/// Size the [BubbleMessage] class to the intrinsic width of the child.
return IntrinsicWidth(
/// Replace [Card] with your [Bubble] class.
child: Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
/// This ensures that the column height only take up as
/// much height as needed by the children.
mainAxisSize: MainAxisSize.min,
children: [
/// This is your content.
Text(message, style: const TextStyle(fontSize: 20.0)),
const SizedBox(height: 5.0),
/// This is your formatted time. We align it to the right.
Align(
alignment: Alignment.centerRight,
child: Text(
DateFormat("hh:mm a").format(DateTime.now()),
style: const TextStyle(fontSize: 20.0),
),
),
],
),
),
);
}
}
Wrap timestamp text in Row and with mainaxisalignment set to end.
Use crossAxisAlignment: CrossAxisAlignment.end,
on Column
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
content,
Another solution is
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: widget.isMyMessage! ? MainAxisAlignment.end : MainAxisAlignment.start,
children: [ widget.isMyMessage! == true
? Padding(
padding: const EdgeInsets.only(right: 4.0),
child: Image.asset(
icRead,
height: 16,
width: 16,
),
)
: Container(),
timeData != null ? Text( timeForChatMsg( timeData ),
style: TextStyle(
fontSize: fontSize12,
color: widget.isMyMessage! ? Colors.white : Colors.black,
),
)
: Container(); ,
widget.isMyMessage! == false
? Padding(
padding: const EdgeInsets.only(left: 4.0),
child: Image.asset(
icRead,
color: primaryColor,
height: 16,
width: 16,
),
)
: Container(),
],
)
Using IntrinsicWidth
and Align
solved my issue.
Here is the result:
return Align(
alignment: alignment,
child: Bubble(
margin: BubbleEdges.only(
top: 10,
left: leftMargin,
right: rightMargin,
),
color: backgroundColor,
nip: bubbleNip,
child: IntrinsicWidth( // <--- here
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
content,
const SizedBox(height: 5),
Align(
alignment: Alignment.centerRight, // <--- here
child: Text(timeFormat01(timestamp)),
),
],
),
),
),
);
Read more about IntrinsicWidth
use cases and documentation .
Note:
This class is relatively expensive. Avoid using it where possible.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.