Search code examples
flutterdartwidgetappbar

How to position a widget in middle of custom appbar Flutter


EDIT: I want the icon to go in the circle that i have created, but i do now seem to succeed using Stack and Positioned:

actions: <Widget>[
        Stack(
          children: [
            Positioned(
              child: CircleAvatar(
                backgroundImage: AssetImage("assets/images/person.jpeg"),
                radius: 30,
                key: Key("1"),
              ),
              top: height,
              right: width/2,
            ),
            Padding(
              padding: EdgeInsets.only(),
            )
          ],

where the width and height are

final double height = MediaQuery.of(context).size.height;
final double width = MediaQuery.of(context).size.width;

ORIGINAL POST: So i have been trying to make a custom appbar in flutter but the image i want to display in the middle of the page does not go where i need it to go.

Here is what i have so far, what i want is the image to be displayed in the center of the appbar(width/2 - radius) and with the full height (height - radius).

https://i.sstatic.net/eyZGN.png

Thanks for your help!!

class ProfileAppBar extends StatelessWidget implements PreferredSizeWidget {
  final String name;
  ProfileAppBar({this.name});
  Size get preferredSize => new Size.fromHeight(kToolbarHeight);
  @override
  Widget build(BuildContext context) {
    final double height = MediaQuery.of(context).size.height;
    final double width = MediaQuery.of(context).size.width;

    return AppBar(
      shape: CustomShapeBorder(),
      leading: Row(
        children: [
          IconButton(
            icon: Icon(Icons.home),
            onPressed: () {
              Navigator.pushReplacementNamed(context, "/home");
            },
          ),
        ],
      ),
      title: Text(name ?? 'Username'),
      actions: <Widget>[
        Padding(
          child: CircleAvatar(
            backgroundImage: AssetImage("assets/images/person.jpeg"),
            radius: 30,
            key: Key("1"),
          ),
          padding: EdgeInsets.only(right: width / 4 + 20),
        ),
        IconButton(
          iconSize: 30,
          icon: Icon(Icons.settings),
          alignment: Alignment.centerRight,
          padding: EdgeInsets.only(right: 20),
          onPressed: () {
            final profileRoute = "/profile";
            bool isNewRouteSameAsCurrent = false;

            Navigator.popUntil(context, (route) {
              if (route.settings.name == profileRoute) {
                isNewRouteSameAsCurrent = true;
              }
              return true;
            });

            if (!isNewRouteSameAsCurrent) {
              Navigator.pushReplacementNamed(context, profileRoute);
            }
          },
        )
      ],
    );
  }
}

class CustomShapeBorder extends ContinuousRectangleBorder {
  @override
  Path getOuterPath(Rect rect, {TextDirection textDirection}) {
    Path path = Path();
    path.lineTo(0, rect.height);

    path.lineTo(rect.width, rect.height);
    path.lineTo(rect.width, 0);
    path.addOval(
      Rect.fromCircle(
        center: Offset(rect.width / 2, rect.height),
        radius: 40,
      ),
    );
    path.addOval(
      Rect.fromCircle(
        center: Offset(rect.width / 2, rect.height),
        radius: 40,
      ),
    );

    return path;[enter image description here][1]
  }
}

Solution

  • You can wrap entire AppBar with Stack

    Stack(
            children: [
              AppBar(
                shape: CustomShapeBorder(),
                leading: Row(
                  children: [
                    IconButton(
                      icon: Icon(Icons.home),
                      onPressed: () {
                        Navigator.pushReplacementNamed(context, "/home");
                      },
                    ),
                  ],
                ),
                title: Text('Username'),
                actions: <Widget>[
                  IconButton(
                    iconSize: 30,
                    icon: Icon(Icons.settings),
                    alignment: Alignment.centerRight,
                    padding: EdgeInsets.only(right: 20),
                    onPressed: () {
                      final profileRoute = "/profile";
                      bool isNewRouteSameAsCurrent = false;
                      Navigator.popUntil(context, (route) {
                        if (route.settings.name == profileRoute) {
                          isNewRouteSameAsCurrent = true;
                        }
                        return true;
                      });
    
                      if (!isNewRouteSameAsCurrent) {
                        Navigator.pushReplacementNamed(context, profileRoute);
                      }
                    },
                  )
                ],
              ),
              Positioned(
                left: 0.0,
                right: 0.0,
                child: CircleAvatar(
                  backgroundImage: AssetImage("assets/images/person.jpeg"),
                  radius: 30,
                  key: Key("1"),
                ),
              ),
            ],
          ),