Home > Software engineering >  Flutter Collapsible Appbar with custom layout and animation
Flutter Collapsible Appbar with custom layout and animation

Time:07-24

I am trying to create an app bar that looks like the following image when expanded

enter image description here

When collapsing I only need the initial column of text to be available in the app bar, so the image should fade away and the text column to animate and become the Appbar title

I have tried using SliverAppBar with a custom scroll view but the Flexible space's title is not looking good also I don't know how to make the image disappear alone and show only the text when collapsed.

As of now, this is the expanded state

enter image description here

And when I try to collapse it, this happens

enter image description here

Here's the code for the same

CustomScrollView(
    slivers: [
      SliverAppBar(
          pinned: true,
          leading: GestureDetector(
            onTap: () => Get.back(),
            child: const Icon(
              Icons.arrow_back,
              color: Colors.black,
            ),
          ),
          flexibleSpace: FlexibleSpaceBar(
            title: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              child: Row(
                children: [
                  const Expanded(
                    child: Text.rich(
                      TextSpan(
                          text: "Buffet Deal\n",
                          style:
                              TextStyle(color: Colors.black, fontSize: 14),
                          children: [
                            TextSpan(
                              text: "Flash Deal",
                              style: TextStyle(
                                  color: Colors.black, fontSize: 10),
                            ),
                          ]),
                    ),
                  ),
                  if (_model.imgUrl != null)
                    CachedNetworkImage(
                      imageUrl: _model.imgUrl!,
                    ),
                  const SizedBox(
                    width: 18,
                  )
                ],
              ),
            ),
          ),
          expandedHeight: Get.height * 0.2,
          backgroundColor: const Color(0xFFFFF4F4)),
      SliverToBoxAdapter(
        child: Container()
      )
    ],
  ),

Your help is appreciated. Thanks in advance

CodePudding user response:

To make the SliverAppBar's flexible space image disappear whenever the expanded space collapse just use the Screenshot

import 'dart:math';

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final expandedHeight = MediaQuery.of(context).size.height * 0.2;
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          SliverAppBar(
            pinned: true,
            leading: GestureDetector(
              onTap: () => {},
              child: const Icon(
                Icons.arrow_back,
                color: Colors.black,
              ),
            ),
            flexibleSpace: LayoutBuilder(builder: (context, constraints) {
              final fraction =
                  max(0, constraints.biggest.height - kToolbarHeight) /
                      (expandedHeight - kToolbarHeight);
              return FlexibleSpaceBar(
                title: Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 16.0),
                  child: Row(
                    children: [
                      Expanded(
                        child: Padding(
                          padding: EdgeInsets.only(left: 24 * (1 - fraction)),
                          child: const Text.rich(
                            TextSpan(
                                text: "Buffet Deal\n",
                                style: TextStyle(
                                    color: Colors.black, fontSize: 14),
                                children: [
                                  TextSpan(
                                    text: "Flash Deal",
                                    style: TextStyle(
                                        color: Colors.black, fontSize: 10),
                                  ),
                                ]),
                          ),
                        ),
                      ),
                      const SizedBox(width: 18)
                    ],
                  ),
                ),
                background: Align(
                  alignment: Alignment.centerRight,
                  child: Image.network(
                    "https://source.unsplash.com/random/400x225?sig=1&licors",
                  ),
                ),
              );
            }),
            expandedHeight: MediaQuery.of(context).size.height * 0.2,
            backgroundColor: const Color(0xFFFFF4F4),
          ),
          const SliverToBoxAdapter(child: SizedBox(height: 1000))
        ],
      ),
    );
  }
}
  • Related