簡體   English   中英

如何使容器小部件僅占用顫振所需的空間?

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

我正在使用顫振開發聊天應用程序。 在那,我必須創建一個包含消息的聊天屏幕。 我希望每個消息容器只占用所需的空間。 例如:短消息、短容器寬度和長消息、長容器。 目前,無論消息的長度如何,它都會占用Column容器的全部空間。

作為旁注,我嘗試將消息容器包裝在靈活的內部,但它根本不起作用。

這是我的代碼:

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),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

如果有界, Align小部件會根據其傳入約束Align自身大小,並且帶有裝飾的Container放置在它周圍。 這意味着裝飾將覆蓋列的整個寬度。 為了解決這個問題, DecoratedBox (由Container生產)需要是Align的后代。

您可能已經注意到的另一個問題是,如果傳入的約束已經有界,則LimitedBox什么也不做。 為了收緊現有的界限,您需要在您的Container (或等效的ConstrainedBox小部件)中提供constraints 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