SliverAppBar have an image as a background, circle avatar and title

Issue

I am trying to achieve something similar to this where I have background, circle avatar, and title, and when scrolling up the avatar disappears but the title remains.
What I have been able to do is get the background image applied, and the sliver title to remain but I cannot work out how to have title outside the FlexibleSpaceBar, nor how to have the CircleAvatar 50% over the background.

enter image description here

SliverAppBar.large(
          expandedHeight: 200.0,
          floating: true,
          pinned: true,
          snap: true,
          flexibleSpace: FlexibleSpaceBar(
            title: _buildProfileName(user),
            background: Stack(
              children: [
                Container(
                  decoration: const BoxDecoration(
                    image: DecorationImage(
                      colorFilter: ColorFilter.mode(
                          Colors.black54, BlendMode.darken),
                      image: AssetImage(
                          "assets/images/landing/hedge-trimmer.jpg"),
                      fit: BoxFit.cover,
                    ),
                  ),
                ),
                Positioned(
                  top:
                      175.0, // (background container size) - (circle height / 2)
                  left: MediaQuery.of(context).size.width / 2 - 50,
                  child: Center(
                    child: CircleAvatar(
                      child: CircleAvatar(
                        backgroundImage: (user.profileImageUrl!.isEmpty
                                ? const AssetImage('assets/images/Logo.png')
                                : CachedNetworkImageProvider(
                                    user.profileImageUrl!))
                            as ImageProvider<Object>?,
                        radius: 45,
                      ),
                      radius: 50,
                      backgroundColor: Colors.white,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),

This above produces something that is close to what I am after just not completely

enter image description here

Solution

I think you are almost there. You can expand the SliverAppBar to include the bottom white space below. Here is the example code:

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

  @override
  Widget build(BuildContext context) {
    final expandedHeight = 500.0;
    final collapsedHeight = 60.0;
    return CustomScrollView(
      slivers: [
        SliverAppBar(
          expandedHeight: expandedHeight,
          collapsedHeight: collapsedHeight,
          floating: true,
          pinned: true,
          snap: true,
          backgroundColor: Colors.white,
          flexibleSpace: FlexibleSpaceBar(
            collapseMode: CollapseMode.pin,
            title: Text('Title',
                style: TextStyle(fontSize: 28, color: Colors.black)),
            background: Stack(
              children: [
                Align(
                  alignment: Alignment.topCenter,
                  child: Container(
                    height: expandedHeight - collapsedHeight - 80,
                    decoration: const BoxDecoration(
                      image: DecorationImage(
                        colorFilter:
                            ColorFilter.mode(Colors.black54, BlendMode.darken),
                        image: NetworkImage('https://picsum.photos/1024'),
                        fit: BoxFit.cover,
                      ),
                    ),
                  ),
                ),
                Positioned(
                  bottom: collapsedHeight + 30,
                  left: MediaQuery.of(context).size.width / 2 - 50,
                  child: Container(
                    padding: EdgeInsets.all(5),
                    decoration: ShapeDecoration(
                      color: Colors.white,
                      shape: CircleBorder(),
                    ),
                    child: CircleAvatar(
                      backgroundImage:
                          NetworkImage('https://picsum.photos/256'),
                      radius: 45,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
        for (int i = 0; i < 10; i++)
          SliverToBoxAdapter(
            child: Container(
              height: 200,
              color: i % 2 == 0 ? Colors.grey : Colors.grey.shade300,
            ),
          )
      ],
    );
  }
}

enter image description here

Answered By – yellowgray

Answer Checked By – Robin (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *