Flutter выравнивает определенный виджет в столбце с минимальной шириной

Я реализую чат в своем приложении 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,
              ),
            ),
          ),
        ],
      ),
    );

2 ответа

Решение

Это действительно не так просто, потому что вы хотите, чтобы пузырек имел «неопределенную» ширину - он должен адаптироваться к длине фактического сообщения, которая не известна до фактического размещения / рисования виджета во время выполнения. Я предлагаю использовать 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,
                ),
              ),
            ),
          ],
        ),
      ),
    ),
  ),
),

Замените это:

      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,
          ),
        )],
      ),
Другие вопросы по тегам