2

I am trying to position a Chip in the top right of a CircleAvatar similar to the below, but cant seem to be able to move it

enter image description here

SizedBox(
                      width: 50,
                      height: 50,
                      child: Stack(
                        children: [
                          CircleAvatar(
                            radius: 50,
                            backgroundColor: Colors.indigo,
                            child: Stack(
                              children: const [
                                Align(
                                  alignment: Alignment.topRight,
                                  child: Chip(
                                      label: Text('7'),
                                      side: BorderSide(
                                        color: Colors.white,
                                        width: 1,
                                      )),
                                )
                              ],
                            ),
                          ),
                        ],
                      ),
                    ),

The above code is producing this enter image description here

Boss Nass
  • 3,384
  • 9
  • 48
  • 90
  • user [this](https://pub.dev/packages/badges) package – Ravindra S. Patil Dec 29 '22 at 12:59
  • yeah we dont want to use a 3rd package but thanks – Boss Nass Dec 29 '22 at 13:03
  • I copied your code but cannot reproduce the problem. For me the number is at the top right corner. – MaLa Dec 29 '22 at 13:07
  • @BossNass refer my [below](https://stackoverflow.com/a/74951515/13997210) I have try without 3rd package hope its help to you – Ravindra S. Patil Dec 29 '22 at 13:12
  • It seems like this happens in Android but not in web. I have not tested iOS or desktop yet. – MaLa Dec 29 '22 at 13:21
  • It seems like that different platforms force the size of the chip differently. You can read more here https://api.flutter.dev/flutter/material/ThemeData/materialTapTargetSize.html. According to that, this answer seems best https://stackoverflow.com/a/74951502/14493188 – MaLa Dec 29 '22 at 13:30

4 Answers4

1

By setting materialTapTargetSize: MaterialTapTargetSize.shrinkWrap on Chip widget you force it to take as little space as it needs.

SizedBox(
  width: 100,
  height: 100,
  child: Stack(
    children: const [
      CircleAvatar(
        radius: 50,
        backgroundColor: Colors.indigo,
      ),
      Positioned(
        top: 0,
        right: 0,
        child: Chip(
          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
          label: Text('7'),
          side: BorderSide(
            color: Colors.white,
            width: 1,
          ),
        ),
      ),
    ],
  ),
)
Ante Bule
  • 1,834
  • 1
  • 2
  • 8
1

You do not require nested Stack and you are missing the heirarchy in placing the widgets. And set materialTapTargetSize to MaterialTapTargetSize.shrinkWrap which will remove the default padding around the chip. And force it to shrink to its size

Mistake in your code:

Stack
 | CircularAvatar
   | Stack          <-- Not needed
     | Align

Correct code:

Stack
  | CircularAvatar
  | Align           <-- Should be in same hierarchy as CircularAvatar

Try the following code:

SizedBox(
        height: 100,
        width: 100,
        child: Stack(
          children: const [
            CircleAvatar(
              backgroundColor: Colors.amber,
              radius: 50,
              backgroundImage: NetworkImage(
                  'https://th.bing.com/th/id/OIP.KZ9jKGoLM_wXMX6aHCB6oAHaEY?pid=ImgDet&rs=1'),
            ),
            Align(
              alignment: Alignment.topRight,
              child: Chip(
                materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                label: Text(
                  '78',
                  style: TextStyle(
                    color: Colors.white,
                  ),
                ),
                padding: EdgeInsets.zero,
                labelPadding: EdgeInsets.symmetric(horizontal: 10),
                backgroundColor: Colors.black
              ),
            )
          ],
        ),
      ),

Output:

enter image description here

krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88
0

Try below code

 Stack(
      children: <Widget>[
        CircleAvatar(child: FlutterLogo(),),
        new Positioned(
          top: 0,
          right: 0,
          child: new Container(
            padding: EdgeInsets.all(1),
            decoration: new BoxDecoration(
              color: Colors.red,
              borderRadius: BorderRadius.circular(6),
            ),
            constraints: BoxConstraints(
              minWidth: 15,
              minHeight: 15,
            ),
            child: new Text('11',
              style: new TextStyle(
                color: Colors.white,
                fontSize: 11,
              ),
              textAlign: TextAlign.center,
            ),
          ),
        )
      ],
    ),

Result-> image

Ravindra S. Patil
  • 11,757
  • 3
  • 13
  • 40
-1

There is no need for a nested stack to achieve this. I simply wrapped the Chip in a FittedBox and then the FittedBox in a SizedBox. The thing to understand here is that the CircleAvatar has to be smaller than the main SizedBox and the Chip has to be smaller than the CircleAvatar in order for these to be stacked properly. For that I've used three variables where mainSize is the size of the main SizedBox, radius is the radius of the CircleAvatar and it is two third of the mainSize, avatarSize is the size of the SizedBox containing the Chip and is one half of the radius (or one third of the mainSize).

Here is the revised code:

double mainSize = 50;
double radius = mainSize * 2 / 3;
double avatarSize = radius / 2;

SizedBox(
            width: mainSize,
            height: mainSize,
            child: Stack(
              children: [
                CircleAvatar(
                  radius: radius,
                  backgroundColor: Colors.indigo,
                  child: Text('BN'),
                ),
                Align(
                  alignment: Alignment.topRight,
                  child: SizedBox(
                    width: avatarSize,
                    height: avatarSize,
                    child: FittedBox(
                      child: Chip(
                        label: Text('17'),
                        side: BorderSide(
                          color: Colors.white,
                          width: 1,
                        ),
                      ),
                    ),
                  ),
                )
              ],
            ),
          ),

Hope it helps!

Shahood ul Hassan
  • 745
  • 2
  • 9
  • 19