简体   繁体   English

如何使容器小部件仅占用颤振所需的空间?

[英]How to make Container widget take only the required space in flutter?

I am working on a chat application using flutter.我正在使用颤振开发聊天应用程序。 In that, I have to create a chat screen containing messages.在那,我必须创建一个包含消息的聊天屏幕。 I want each message container to take only the required space.我希望每个消息容器只占用所需的空间。 For example: Short message, short container width & Long message, long container.例如:短消息、短容器宽度和长消息、长容器。 Currently, it's taking full space of the Column container no matter what's the length of the message.目前,无论消息的长度如何,它都会占用Column容器的全部空间。

As a side note, I have tried wrapping the message container inside flexible but it didn't work at all.作为旁注,我尝试将消息容器包装在灵活的内部,但它根本不起作用。

Here's my code:这是我的代码:

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 && data.data[chatId] != null) {
                        return buildChatMessagesUI(
                            context, data.data[chatId].messages);
                      } else {
                        return Text("No Data");
                      }
                    },
                  ),
                ),
                buildMessageInputUI(chatId: chatId),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

The Align widget sizes itself to its incoming constraints if bounded, and your Container with a decoration is placed around it.如果有界, Align小部件会根据其传入约束Align自身大小,并且带有装饰的Container放置在它周围。 This means the decoration will cover the entire width of the column.这意味着装饰将覆盖列的整个宽度。 To fix this, the DecoratedBox (produced by Container ) needs to be a descendant of Align instead.为了解决这个问题, DecoratedBox (由Container生产)需要是Align的后代。

Another problem you may have noticed is that LimitedBox does nothing if the incoming constraint is already bounded.您可能已经注意到的另一个问题是,如果传入的约束已经有界,则LimitedBox什么也不做。 In order to tighten the existing bound, you will need to provide constraints in your Container (or equivalently, a ConstrainedBox widget).为了收紧现有的界限,您需要在您的Container (或等效的ConstrainedBox小部件)中提供constraints FractionallySizedBox might also be worth considering. 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,
        ),
      ),
    ),
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM