【问题标题】:Flutter Container - How to align child text without changing container width?Flutter Container - 如何在不更改容器宽度的情况下对齐子文本?
【发布时间】:2019-12-26 09:28:33
【问题描述】:

我正在尝试构建类似于聊天气泡的东西,其中每个聊天气泡的文本都会正常对齐,并且时间戳与气泡的右下角对齐。气泡的大小必须随着文本而扩大,并且不应占用过多的空间。

为了做到这一点,我使用了一个带有两个 Container 孩子的 Column。第二个孩子将拥有时间戳。

当我在不向第二个 Container 子项添加“对齐”属性的情况下执行此操作时,气泡大小会正确收缩/扩展为文本,如下所示:

但是当我将alignment: Alignment.bottomRight 添加到第二个容器时,气泡大小会扩大以填满屏幕的整个宽度。

有没有办法在不扩大气泡大小的情况下将“7:30 PM”文本对齐气泡的右下角?

Scaffold(
        body: Container(
          decoration: BoxDecoration(
            color: Colors.blue,
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Container(
                child: Text(
                  "Without Alignment",
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
                ),
              ),
              Container(
//                alignment: Alignment.bottomRight,
                decoration: BoxDecoration(
                  border: Border.all(),
                ),
                child: Text(
                  "7:30 PM",
                  textDirection: TextDirection.rtl,
                  textAlign: TextAlign.right,
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
                ),
              ),
            ],
          ),
        ),
      ),

【问题讨论】:

    标签: flutter containers


    【解决方案1】:

    这可能对你有帮助

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: MainWidget(),
        );
      }
    }
    
    class MainWidget extends StatefulWidget {
      @override
      _MainWidgetState createState() => _MainWidgetState();
    }
    
    class _MainWidgetState extends State<MainWidget> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: ListView(
            shrinkWrap: true,
            children: <Widget>[
              ReceivedMessageBubble(
                message:
                    "This is a demo message send by XXXX. So don't reply it. Trying to making it multiple lines. You can increase it",
                time: "12:45 PM",
              ),
              SendMessageBubble(
                message:
                    "Oh!!! OK",
                time: "12:45 PM",
              ),
            ],
          ),
        );
      }
    }
    
    class SendMessageBubble extends StatelessWidget {
      final String message;
      final String time;
    
      const SendMessageBubble({
        Key key,
        this.message,
        this.time,
      })  : assert(message != null),
            assert(time != null),
            super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return LayoutBuilder(
          builder: (context, constraints) {
            double maxBubbleWidth = constraints.maxWidth * 0.7;
            return Align(
              alignment: Alignment.centerRight,
              child: ConstrainedBox(
                constraints: BoxConstraints(maxWidth: maxBubbleWidth),
                child: Container(
                  decoration: BoxDecoration(
                    color: Colors.blue[300],
                    borderRadius: const BorderRadius.only(
                      topLeft: Radius.circular(10.0),
                      topRight: Radius.circular(0.0),
                      bottomLeft: Radius.circular(10.0),
                      bottomRight: Radius.circular(10.0),
                    ),
                  ),
                  margin: const EdgeInsets.all(10.0),
                  padding: const EdgeInsets.all(10.0),
                  child: IntrinsicWidth(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children: <Widget>[
                        Text(message),
                        const SizedBox(height: 5.0),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.start,
                          children: <Widget>[
                            Text(
                              time,
                              style: const TextStyle(
                                color: Colors.black54,
                                fontSize: 10.0,
                              ),
                            ),
                          ],
                        )
                      ],
                    ),
                  ),
                ),
              ),
            );
          },
        );
      }
    }
    
    class ReceivedMessageBubble extends StatelessWidget {
      final String message;
      final String time;
    
      const ReceivedMessageBubble({
        Key key,
        this.message,
        this.time,
      })  : assert(message != null),
            assert(time != null),
            super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return LayoutBuilder(
          builder: (context, constraints) {
            double maxBubbleWidth = constraints.maxWidth * 0.7;
            return Align(
              alignment: Alignment.centerLeft,
              child: ConstrainedBox(
                constraints: BoxConstraints(
                  maxWidth: maxBubbleWidth,
                ),
                child: Container(
                  decoration: BoxDecoration(
                    color: Colors.grey[300],
                    borderRadius: const BorderRadius.only(
                      topLeft: Radius.circular(0.0),
                      topRight: Radius.circular(10.0),
                      bottomLeft: Radius.circular(10.0),
                      bottomRight: Radius.circular(10.0),
                    ),
                  ),
                  margin: const EdgeInsets.all(10.0),
                  padding: const EdgeInsets.all(10.0),
                  child: IntrinsicWidth(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Text(message,),
                        const SizedBox(height: 5.0),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.end,
                          children: <Widget>[
                            Text(
                              time,
                              style: const TextStyle(
                                color: Colors.black54,
                                fontSize: 10.0,
                              ),
                            ),
                          ],
                        )
                      ],
                    ),
                  ),
                ),
              ),
            );
          },
        );
      }
    }
    

    这里是演示DartPad

    【讨论】:

    • 这实际上是我正在研究的一个很好的解决方案,并为这个问题展示了一个更好的设计解决方案。谢谢。
    【解决方案2】:

    我编辑了我的答案,试试这个:

    Column(crossAxisAlignment: CrossAxisAlignment.end,  
                    mainAxisSize: MainAxisSize.max,
                    children: <Widget>[
                      Container(
                        child: Text(
                          "Without Alignment",
                          style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
                        ),
                      ),
                       Container( 
                       //alignment: Alignment.bottomRight,
                         //constraints: BoxConstraints.expand(),
                        decoration: BoxDecoration(
                          border: Border.all(),
                        ),
                        child: Text(
                          "7:30 PM",
                          style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
                        ),
                      ),
                    ],
                  );
    

    【讨论】:

    • 其实之前试过这个,但它使气泡一直扩大到屏幕底部,并且“7:30 PM”文本仍然居中。如果我添加对齐属性,气泡将占据整个屏幕。 link
    • 编辑后,这确实有效,但我还必须将 mainAxisSize 设置为 inAxisSize.min,所以我缺少的是 crossAxisAlignment: CrossAxisAlignment.end
    【解决方案3】:

    试试这个,它对我有用..

    Padding(
        padding: const EdgeInsets.all(8.0),
        child: Container(
          width: 300,
          padding: EdgeInsets.all(10),
            decoration: BoxDecoration(
              color: Colors.blue,
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Container(
                  child: Text(
                    "Without Alignment",
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
                  ),
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    Container(
                  decoration: BoxDecoration(
                    border: Border.all(),
                  ),
                  child: Text(
                    "7:30 PM",
                    textDirection: TextDirection.rtl,
                    textAlign: TextAlign.right,
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
                  ),
                ),
                  ],
                )
              ],
            ),
          ),
      ),
    

    【讨论】:

    • 这里您只是将容器宽度设置为 300,这违反了“气泡的大小必须随文本扩展,并且不应占用过多空间”的要求。不过谢谢你的回复..
    猜你喜欢
    • 2014-03-21
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 2011-08-09
    • 2016-05-20
    相关资源
    最近更新 更多