Flutter 以最小宽度对齐列中的特定小部件
Flutter align specific widget in column with min width
我正在我的 flutter 应用程序上实现聊天,我希望我的聊天时间在列的右侧对齐(所有其他小部件应左对齐)。
我的问题是,当我在我的专栏中使用 alignment.bottomRight
时,它会将列宽扩展到 max
(我想保留它 min
)。
问题:
我想要达到的目标:
我的专栏:
return Bubble(
margin: BubbleEdges.only(top: 5, bottom: 5),
elevation: 0.6,
alignment: Alignment.topLeft,
nip: BubbleNip.leftTop,
radius: Radius.circular(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
getUserChatTitle(document['userId']),
Padding(
padding: const EdgeInsets.only(top: 3, bottom: 5),
child: SelectableLinkify(
onOpen: onOpenLink,
text: "Text Text Text",
textAlign:
intl.Bidi.detectRtlDirectionality(document['content'])
? TextAlign.right
: TextAlign.left,
textDirection:
intl.Bidi.detectRtlDirectionality(document['content'])
? ui.TextDirection.rtl
: ui.TextDirection.ltr,
style: TextStyle(
fontSize: 16,
height: 1.35,
letterSpacing: -0.1,
fontFamily: 'Arimo',
),
),
),
Align(
alignment: Alignment.bottomRight,
child: Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
],
),
);
替换为:
Align(
alignment: Alignment.bottomRight,
child: Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
与:
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
)],
),
这确实没那么容易,因为您希望气泡具有“未定义”的宽度 - 它应该适应实际消息的长度,这在运行时实际放置/绘制小部件之前是未知的。我的建议是使用 Stack
- 我也在 ListView.builder
中使用它,这可能是所需的用例。请务必阅读我在代码块中的评论:
ListView.builder(
itemCount: 5,
itemBuilder: (context, index) => UnconstrainedBox(
/// Decide whether a message has been received or written by yourself (left or right side)
alignment:
index % 2 == 0 ? Alignment.centerLeft : Alignment.centerRight,
/// ConstrainedBox to make sure chat bubbles don't go from left to right if they are too big - you can change it or even remove it if it's not what you want
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width / 1.5),
child: Bubble(
margin: BubbleEdges.only(top: 5, bottom: 5),
elevation: 0.6,
/// Alignment and nip has to be adjusted here too
alignment:
index % 2 == 0 ? Alignment.topLeft : Alignment.topRight,
nip: index % 2 == 0 ? BubbleNip.leftTop : BubbleNip.rightTop,
radius: Radius.circular(10),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('TestUser'),
Padding(
padding: const EdgeInsets.only(top: 3, bottom: 5),
child: Text(
'Text ' * Random().nextInt(50),
style: TextStyle(
fontSize: 16,
height: 1.35,
letterSpacing: -0.1,
),
),
),
/// Adjust the space you want between the actual message and the timestamp here, you could also use a Text widget to use the same height as the actual timestamp - as you like
SizedBox(height: 18.0),
],
),
Positioned(
bottom: 0,
right: 0,
child: Text(
'08.09.2021',
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
],
),
),
),
),
),
我正在我的 flutter 应用程序上实现聊天,我希望我的聊天时间在列的右侧对齐(所有其他小部件应左对齐)。
我的问题是,当我在我的专栏中使用 alignment.bottomRight
时,它会将列宽扩展到 max
(我想保留它 min
)。
问题:
我想要达到的目标:
我的专栏:
return Bubble(
margin: BubbleEdges.only(top: 5, bottom: 5),
elevation: 0.6,
alignment: Alignment.topLeft,
nip: BubbleNip.leftTop,
radius: Radius.circular(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
getUserChatTitle(document['userId']),
Padding(
padding: const EdgeInsets.only(top: 3, bottom: 5),
child: SelectableLinkify(
onOpen: onOpenLink,
text: "Text Text Text",
textAlign:
intl.Bidi.detectRtlDirectionality(document['content'])
? TextAlign.right
: TextAlign.left,
textDirection:
intl.Bidi.detectRtlDirectionality(document['content'])
? ui.TextDirection.rtl
: ui.TextDirection.ltr,
style: TextStyle(
fontSize: 16,
height: 1.35,
letterSpacing: -0.1,
fontFamily: 'Arimo',
),
),
),
Align(
alignment: Alignment.bottomRight,
child: Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
],
),
);
替换为:
Align(
alignment: Alignment.bottomRight,
child: Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
与:
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [Text(
formatTimestampToString(document['timestamp']),
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
)],
),
这确实没那么容易,因为您希望气泡具有“未定义”的宽度 - 它应该适应实际消息的长度,这在运行时实际放置/绘制小部件之前是未知的。我的建议是使用 Stack
- 我也在 ListView.builder
中使用它,这可能是所需的用例。请务必阅读我在代码块中的评论:
ListView.builder(
itemCount: 5,
itemBuilder: (context, index) => UnconstrainedBox(
/// Decide whether a message has been received or written by yourself (left or right side)
alignment:
index % 2 == 0 ? Alignment.centerLeft : Alignment.centerRight,
/// ConstrainedBox to make sure chat bubbles don't go from left to right if they are too big - you can change it or even remove it if it's not what you want
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width / 1.5),
child: Bubble(
margin: BubbleEdges.only(top: 5, bottom: 5),
elevation: 0.6,
/// Alignment and nip has to be adjusted here too
alignment:
index % 2 == 0 ? Alignment.topLeft : Alignment.topRight,
nip: index % 2 == 0 ? BubbleNip.leftTop : BubbleNip.rightTop,
radius: Radius.circular(10),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('TestUser'),
Padding(
padding: const EdgeInsets.only(top: 3, bottom: 5),
child: Text(
'Text ' * Random().nextInt(50),
style: TextStyle(
fontSize: 16,
height: 1.35,
letterSpacing: -0.1,
),
),
),
/// Adjust the space you want between the actual message and the timestamp here, you could also use a Text widget to use the same height as the actual timestamp - as you like
SizedBox(height: 18.0),
],
),
Positioned(
bottom: 0,
right: 0,
child: Text(
'08.09.2021',
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
),
],
),
),
),
),
),