SliverAppBar имеет изображение в качестве фона, обведенный аватар и заголовок

Я пытаюсь добиться чего-то похожего на это, когда у меня есть фон, круговой аватар и заголовок, а при прокрутке вверх аватар исчезает, но заголовок остается. Что мне удалось сделать, так это применить фоновое изображение и оставить заголовок ленты, но я не могу понять, как сделать заголовок вне FlexibleSpaceBar или как сделать CircleAvatar на 50% поверх фона.

      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,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),

Это выше дает что-то близкое к тому, что я ищу, просто не полностью

1 ответ

Я думаю, вы почти у цели. Вы можете расширитьSliverAppBarчтобы включить нижнее белое пространство ниже. Вот пример кода:

      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,
            ),
          )
      ],
    );
  }
}

Другие вопросы по тегам