Flutter: View of message sent on whatsapp?

Viewed 964

I want to get this message view, but I can't add clock and blue tick at the end. It should not look distorted when the message gets longer.

enter image description here

I tried such a code but the result was not the same.

Row sentMessage(BuildContext context, int index) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          child: Container(
            constraints: BoxConstraints(
              maxWidth: displayWidth(context) * 0.80,
              minWidth: displayWidth(context) * 0.20,
            ),
            decoration: BoxDecoration(
                color: Color(0xffDCF8C6),
                borderRadius: BorderRadius.all(Radius.circular(9))),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                Container(
                  child: Text(messages[index]),
                ),
                Container(
                  child: Text('11:11'),
                )
              ],
            ),
            margin: EdgeInsets.symmetric(
              horizontal: displayWidth(context) * 0.02,
              vertical: displayWidth(context) * 0.004,
            ),
            padding: EdgeInsets.all(displayWidth(context) * 0.02),
          ),
          alignment: Alignment.centerRight,
          width: displayWidth(context),
        ),
      ],
    );
  }

This is the result

enter image description here

2 Answers

I was able to do it myself after spending some time and thinking.

Row sentMessage(BuildContext context, int index) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          child: Container(
            constraints: BoxConstraints(
              maxWidth: displayWidth(context) * 0.80,
              minWidth: displayWidth(context) * 0.20,
            ),
            decoration: BoxDecoration(
                color: Color(0xffDCF8C6),
                borderRadius: BorderRadius.all(Radius.circular(5))),
            child: Wrap(
              verticalDirection: VerticalDirection.down,
              alignment: WrapAlignment.end,
              children: [
                Container(
                  margin: EdgeInsets.zero,
                  padding: EdgeInsets.only(
                      bottom: displayHeightOutAppBar(context) * 0.005),
                  constraints: BoxConstraints(
                    maxWidth: displayWidth(context) * 0.80,
                  ),
                  child: Text(
                    messages[index],
                    style: TextStyle(
                      fontSize: displayWidth(context) * 0.04,
                      color: Colors.black,
                    ),
                  ),
                ),
                Container(
                  padding: EdgeInsets.zero,
                  margin: EdgeInsets.only(
                      top: displayHeightOutAppBar(context) * 0.006,
                      left: displayWidth(context) * 0.015),
                  //alignment: Alignment.bottomRight,
                  constraints: BoxConstraints(
                    maxWidth: displayWidth(context) * 0.20,
                  ),
                  child: Text(
                    '11:11',
                    style: TextStyle(color: Colors.grey),
                  ),
                ),
                Container(
                  margin: EdgeInsets.only(
                      top: displayHeightOutAppBar(context) * 0.006),
                  child: Icon(
                    Icons.done_all,
                    size: displayWidth(context) * 0.04,
                    color: Colors.blue,
                  ),
                ),
              ],
            ),
            margin: EdgeInsets.symmetric(
              horizontal: displayWidth(context) * 0.02,
              vertical: displayWidth(context) * 0.004,
            ),
            padding: EdgeInsets.only(
                left: displayWidth(context) * 0.015,
                right: displayWidth(context) * 0.015,
                top: displayWidth(context) * 0.015),
          ),
          alignment: Alignment.centerRight,
          width: displayWidth(context),
        ),
      ],
    );
  }

enter image description here

I add an explanation with the recommendation of @gmdev

The wrong thing I did was to place the items one on the other using the "Column".Instead I placed them side by side using "Wrap". I gave "MaxWidth" value to "Containers" that cover the items inside instead of the main "Container".I adjusted the spaces between them with "Padding" and "Margin".

Maybe there are different ways to do this but I think it's the simplest way.Those with different solutions can write

Here I froze again and added the second edit

There is a small triangle on the edge of the first message sent via Whatsapp.The only way to do this is "ClipPath".If your math is not good, you will have to work hard to do this.Couldn't find a similar example on the internet.

enter image description here

Row firstSentMessage(BuildContext context, int index) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          child: ClipPath(
            clipper: MyCustomClipper1(),
            child: Container(
              constraints: BoxConstraints(
                maxWidth: displayWidth(context) * 0.80,
                minWidth: displayWidth(context) * 0.20,
              ),
              decoration: BoxDecoration(
                color: Color(0xffDCF8C6),
                borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(5),
                    bottomLeft: Radius.circular(5),
                    bottomRight: Radius.circular(5)),
              ),
              child: Wrap(
                verticalDirection: VerticalDirection.down,
                alignment: WrapAlignment.end,
                children: [
                  Container(
                    margin: EdgeInsets.zero,
                    padding: EdgeInsets.only(
                        bottom: displayHeightOutAppBar(context) * 0.005),
                    constraints: BoxConstraints(
                      maxWidth: displayWidth(context) * 0.80,
                    ),
                    child: Text(
                      messages[index],
                      style: TextStyle(
                        fontSize: displayWidth(context) * 0.04,
                        color: Colors.black,
                      ),
                    ),
                  ),
                  Container(
                    padding: EdgeInsets.zero,
                    margin: EdgeInsets.only(
                      top: displayHeightOutAppBar(context) * 0.006,
                      left: displayWidth(context) * 0.015,
                    ),
                    //alignment: Alignment.bottomRight,
                    constraints: BoxConstraints(
                      maxWidth: displayWidth(context) * 0.20,
                    ),
                    child: Text(
                      '11:11',
                      style: TextStyle(color: Colors.grey),
                    ),
                  ),
                  Container(
                    margin: EdgeInsets.only(
                      top: displayHeightOutAppBar(context) * 0.006,
                      right: displayWidth(context) * 0.015,
                    ),
                    child: Icon(
                      Icons.done_all,
                      size: displayWidth(context) * 0.04,
                      color: Colors.blue,
                    ),
                  ),
                ],
              ),
              margin: EdgeInsets.symmetric(
                horizontal: displayWidth(context) * 0.01,
                vertical: displayWidth(context) * 0.004,
              ),
              padding: EdgeInsets.only(
                  left: displayWidth(context) * 0.015,
                  right: displayWidth(context) * 0.015,
                  top: displayWidth(context) * 0.015),
            ),
          ),
          alignment: Alignment.centerRight,
          width: displayWidth(context),
          margin: EdgeInsets.only(top: displayHeightOutAppBar(context) * 0.007),
        ),
      ],
    );
  }

And this is "Clipper".

class MyCustomClipper1 extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    Path path = Path();

    path.lineTo(0, size.height);
    path.lineTo(20, size.height);
    path.arcToPoint(Offset(size.width - 12, 13),
        radius: Radius.circular(1), clockwise: false);
    path.lineTo(size.width, 0);

    path.close();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}

I added "ClipPath" and "clipper" for it in new codes.I slightly changed the "padding" and "margin" values to make the image correct.

My Code :

[import 'package:flutter/material.dart';

class OwnMessageCard extends StatelessWidget {
  const OwnMessageCard({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.centerLeft,
      child: ConstrainedBox(
        constraints: BoxConstraints(
          maxWidth: MediaQuery.of(context).size.width - 45,
        ),
        child: Card(
          elevation: 1,
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
          color: Color(0xffdcf8c6),
          margin: EdgeInsets.symmetric(
            horizontal: 15,
            vertical: 5,
          ),
          child: Stack(children: \[
            Padding(
              padding: const EdgeInsets.only(
                left: 10,
                right: 60,
                top: 10,
                bottom: 20,
              ),
              child: Text(
                "Hey, Joy Sinha",
                style: TextStyle(
                  fontSize: 16,
                ),
              ),
            ),
            Positioned(
              bottom: 4,
              right: 10,
              child: Row(
                children: \[
                  Text(
                    "20:58",
                    style: TextStyle(
                      fontSize: 13,
                      color: Colors.grey\[600\],
                    ),
                  ),
                  SizedBox(
                    width: 5,
                  ),
                  Icon(
                    Icons.done_all,
                    size: 20,
                  ),
                \],
              ),
            ),
          \]),
        ),
      ),
    );
  }
}][1]
Related