#flutter #dart
#flutter #dart
Вопрос:
Я работаю над приложением чата с использованием flutter. Для этого мне нужно создать экран чата, содержащий сообщения. Я хочу, чтобы каждый контейнер сообщений занимал только необходимое пространство. Например: короткое сообщение, короткая ширина контейнера и длинное сообщение, длинный контейнер. В настоящее время он занимает все пространство Column
контейнера независимо от длины сообщения.
В качестве примечания я попытался обернуть контейнер сообщений внутри flexible, но это вообще не сработало.
Вот мой код:
import 'package:flutter/material.dart';
import 'package:memomessenger/Services/Chats.dart';
import 'package:memomessenger/Services/Constants.dart';
import 'package:memomessenger/Services/Types/Chat.dart';
import 'package:memomessenger/Services/Types/ChatsActivity.dart';
import 'package:memomessenger/Services/User.dart';
Widget buildMessageWidget(
BuildContext context, Message message, String currentUserId) {
final bool isFromCurrentUser = message.senderId == currentUserId;
return LimitedBox(
maxWidth: MediaQuery.of(context).size.width * .75,
child: Container(
margin: EdgeInsets.symmetric(vertical: 2),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(
isFromCurrentUser ? 0 : messageBorderRadius,
),
topLeft: Radius.circular(
isFromCurrentUser ? messageBorderRadius : 0,
),
bottomLeft: Radius.circular(messageBorderRadius),
bottomRight: Radius.circular(messageBorderRadius),
),
color: isFromCurrentUser ? themeAccentColor[500] : Colors.cyan,
),
child: Align(
alignment:
isFromCurrentUser ? Alignment.centerRight : Alignment.centerLeft,
child: Text(
message.text,
style: TextStyle(
color: isFromCurrentUser ? Colors.white : Colors.black,
),
),
),
),
);
}
Widget buildChatMessagesUI(BuildContext context, List<Message> messages) {
final String currentUserId = currentUser.value.id;
return SingleChildScrollView(
child: Column(
verticalDirection: VerticalDirection.up,
children: messages.reversed.map((Message message) {
return buildMessageWidget(context, message, currentUserId);
}).toList(),
),
);
}
Widget buildMessageInputUI({@required String chatId}) {
final String currentUserId = currentUser.value.id;
return TextFormField(
decoration: const InputDecoration(
hintText: 'Enter your email',
),
onChanged: (String message) {
sendMessage(chatId, Message(text: message, senderId: currentUserId));
},
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
autofocus: true,
autocorrect: true,
keyboardType: TextInputType.multiline,
);
}
class ChatActivity extends StatelessWidget {
final String chatId;
ChatActivity({@required this.chatId});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: StreamBuilder<Map<String, Chat>>(
stream: chatActivityChatList,
initialData: {},
builder: (BuildContext context,
AsyncSnapshot<Map<String, Chat>> data) {
if (data.hasData amp;amp; data.data[chatId] != null) {
return buildChatMessagesUI(
context, data.data[chatId].messages);
} else {
return Text("No Data");
}
},
),
),
buildMessageInputUI(chatId: chatId),
],
),
),
),
),
);
}
}
Комментарии:
1. Измените столбец MainAxisSize на MainAxisSize.min, который будет вести себя как wrap_content . Дайте мне знать, если это сработает для вас, я опубликую полный ответ.
2. Нет, тот же результат! Пожалуйста, помогите мне!
3. Вы имеете в виду, что он занимает всю ширину
Column
? Высота здесь не должна быть проблемой.4. i.imgur.com/D35N68m.jpeg это результат
Ответ №1:
Align
Размер виджета соответствует его входящим ограничениям, если он ограничен, и ваш Container
с украшением размещается вокруг него. Это означает, что оформление будет охватывать всю ширину столбца. Чтобы исправить это, DecoratedBox
(созданный Container
) должен быть потомком Align
вместо этого.
Другая проблема, которую вы, возможно, заметили, заключается в том, что LimitedBox
ничего не делает, если входящее ограничение уже ограничено. Чтобы ужесточить существующую привязку, вам нужно будет предоставить constraints
в вашем Container
(или, что эквивалентно, ConstrainedBox
виджете). FractionallySizedBox
также может стоить рассмотреть.
Widget buildMessageWidget(
BuildContext context, Message message, String currentUserId) {
final bool isFromCurrentUser = message.senderId == currentUserId;
return Align(
alignment:
isFromCurrentUser ? Alignment.centerRight : Alignment.centerLeft,
child: Container(
margin: EdgeInsets.symmetric(vertical: 2),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * .75
),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(
isFromCurrentUser ? 0 : messageBorderRadius,
),
topLeft: Radius.circular(
isFromCurrentUser ? messageBorderRadius : 0,
),
bottomLeft: Radius.circular(messageBorderRadius),
bottomRight: Radius.circular(messageBorderRadius),
),
color: isFromCurrentUser ? themeAccentColor[500] : Colors.cyan,
),
child: Text(
message.text,
style: TextStyle(
color: isFromCurrentUser ? Colors.white : Colors.black,
),
),
),
);
}
Комментарии:
1. Большое вам спасибо за ваши усилия! Да благословит вас Бог!!