Michael T
Michael T

Reputation: 816

Flutter: How to make circular avatar in appbar

Good day, I am struggling to make my avatar in the top right of the appbar a perfect circle. It keeps coming out oval.

enter image description here

I've tried many options (including setting the radius, using ClipRRect, ClipOval, etc) and it doesn't seem to affect the shape of the rounded edges.

Code:

return Scaffold(
  appBar: AppBar(
    automaticallyImplyLeading: false,
      backgroundColor: COLORS_BG,
      title: Padding(
        padding: const EdgeInsets.only(top: 10.0),
        child: Row(
          children: <Widget>[
            Image.asset('images/localhourlogo.png', height: 50.0,),
          ]
        ),
      ),
      actions: <Widget>[
        PopupMenuButton<String>(
          icon: CircleAvatar(
            backgroundImage: NetworkImage(googleUserUrl)
          ),
          onSelected: choiceAction,
          itemBuilder: (BuildContext context) {
            return MenuItems.choices.map((String choice) {
              return PopupMenuItem<String> (
                value: choice,
                child: Text(choice),
              );
            }).toList();
          },
        )
      ],

Goal: to make the avatar a pure circle and not this oval shape.

Tried: ClipRRect, ClipOval, setting radius min and max, etc

Thank you for any and all help.

Upvotes: 2

Views: 15773

Answers (5)

Jay Dangar
Jay Dangar

Reputation: 3469

You can use ClipOval Widget to do that. I am posting an example where my image will be leading icon widget in rounded format just like in native android.

AppBar(
      title: Text(title),
      leading: Padding(
        padding: const EdgeInsets.all(8.0),
        child: ClipOval(
          child: Image(image: Image.asset('assets/images/icon.webp').image,),
        ),
      ),
    );

Upvotes: 0

Michael T
Michael T

Reputation: 816

Here is my final solution thanks in big part to João Soares. Adjusting the width increases the size of the circle. I made it equal to the height of the "localhour" image, and now it looks great.

actions: <Widget>[
                  Container(
                    width: 60.0,
                    child: PopupMenuButton<String>(
                      icon: ClipOval(
                        child: Align(
                          heightFactor: 1,
                          widthFactor: 1,
                          child: Image.network(googleUserUrl),
                        ),
                      ),
                      onSelected: choiceAction,
                      itemBuilder: (BuildContext context) {
                        return MenuItems.choices.map((String choice) {
                          return PopupMenuItem<String> (
                            value: choice,
                            child: Text(choice),
                          );
                        }).toList();
                      },
                    ),
                  )
                ],

enter image description here

Upvotes: 0

J. S.
J. S.

Reputation: 9625

I've had this issue in the past and have found that wrapping the AvatarCircle in a container with 58 width fixes the Circle radius ratio issue, making it a proper circle shape. One pixel more or less may fit your liking. Give this a try:

Container(
  width: 58,
  child: PopupMenuButton(
    icon: CircleAvatar(
      backgroundImage: NetworkImage(
        "https://4.bp.blogspot.com/-Jx21kNqFSTU/UXemtqPhZCI/AAAAAAAAh74/BMGSzpU6F48/s1600/funny-cat-pictures-047-001.jpg"
      ),
      backgroundColor: Colors.red,
    ),
    itemBuilder: (BuildContext context) {
      return [
        PopupMenuItem<String> (
          value: '1',
          child: Text('1'),
        ),
        PopupMenuItem<String> (
          value: '2',
          child: Text('2'),
        ),
      ];
    },
  ),
)

Upvotes: 5

Michael T
Michael T

Reputation: 816

This was the solution I found, but now my issue is that I can't make the avatar bigger than what is shown below.

actions: <Widget>[
                  PopupMenuButton<String>(
                    icon: Container(
                      child: ClipOval(
                        child: Align(
                          heightFactor: 1,
                          widthFactor: 1,
                          child: Image.network(googleUserUrl),
                        ),
                      )
                    ),

enter image description here


With João Soares code:

Container(
  padding: EdgeInsets.all(5),
  width: 58,
  child: CircleAvatar(
    backgroundImage: NetworkImage(
      "https://4.bp.blogspot.com/-Jx21kNqFSTU/UXemtqPhZCI/AAAAAAAAh74/BMGSzpU6F48/s1600/funny-cat-pictures-047-001.jpg"
    )
  ),
),

enter image description here


With dumazy code:

actions: <Widget>[
                  PopupMenuButton<String>(
                    icon: Container(
                      child: ClipOval(
                        child: Align(
                          heightFactor: 1,
                          widthFactor: 1,
                          child: Image.network(googleUserUrl),
                        ),
                      )
                    ),

enter image description here


Thoughts?

Upvotes: 0

dumazy
dumazy

Reputation: 14435

Normally it should work with ClipRRect. Make sure you add fit: BoxFit.cover to avoid scaling.

ClipRRect(
  borderRadius: BorderRadius.circular(25.0),
  child: Image.network(
    googleUserUrl,
    height: 50.0,
    width: 50.0,
    fit: BoxFit.cover,
  ),
),

Upvotes: 2

Related Questions