image

27 Feb 2026

9K

35K

Creating Custom AppBar Widgets with FlexibleSpace in Flutter

Flutter's declarative UI framework provides powerful tools for crafting rich and dynamic user interfaces. One area where this power truly shines is in building custom AppBars. While the standard AppBar widget is robust for most cases, scenarios often arise where a more interactive, scrolling-dependent AppBar is desired—think of expanding headers with parallax effects, dynamic images, or complex layouts that change as the user scrolls. This is where FlexibleSpace, in conjunction with SliverAppBar, becomes indispensable.

Enhancing User Experience with Dynamic AppBars

A dynamic AppBar can significantly improve the user experience by making navigation more intuitive and visually engaging. Instead of a static header, you can create AppBars that react to user scrolls, revealing more information, transitioning images, or changing their layout based on the scroll position. This responsiveness is a hallmark of modern mobile applications.

The Power of FlexibleSpace

At its core, FlexibleSpace is a widget that occupies the entire available space behind a SliverAppBar's toolbar. It expands and collapses as the user scrolls, providing a canvas for highly customizable and interactive header content. To utilize FlexibleSpace, you must use a SliverAppBar within a CustomScrollView, as FlexibleSpace's behavior is intrinsically linked to the scrolling mechanics of slivers.

Key Components for a Dynamic AppBar

  • SliverAppBar: A material design app bar that integrates with a CustomScrollView. It can expand and collapse as the user scrolls.
  • flexibleSpace: A widget that is stacked behind the toolbar and the tab bar. Its height will be the expandedHeight and it will collapse down to the height of the toolbar and the tab bar. You can place any widget here, often an Expanded widget containing a Stack or LayoutBuilder.
  • Expanded: Used within flexibleSpace to make its child fill the available space.
  • LayoutBuilder: This widget can be incredibly useful within flexibleSpace to read the current constraints (specifically, the height) of the AppBar as it expands and collapses. This allows you to dynamically adjust the appearance of your content (e.g., scale an image, change text size) based on the AppBar's current height.
  • Stack: Often used inside flexibleSpace to layer multiple widgets, such as a background image and an overlaying title or gradient.

Step-by-Step Implementation

Let's create a practical example of a custom AppBar that expands to show a background image and a title, then collapses to just the title as the user scrolls.

Project Setup

Start with a basic Flutter application. We will modify the _MyHomePageState to include our custom AppBar.

Building the Custom SliverAppBar

The core of our custom AppBar will be a SliverAppBar widget. Pay close attention to the flexibleSpace property.


import 'package:flutter/material.dart';

class CustomSliverAppBar extends StatelessWidget {
  final String title;
  final String imageUrl;

  const CustomSliverAppBar({
    Key? key,
    required this.title,
    required this.imageUrl,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SliverAppBar(
      expandedHeight: 200.0, // Height when fully expanded
      floating: false,       // Does not float over the content
      pinned: true,          // Stays visible at the top when collapsed
      snap: false,           // No snap behavior

      flexibleSpace: FlexibleSpaceBar(
        centerTitle: true,
        title: Text(
          title,
          style: TextStyle(color: Colors.white, fontSize: 20.0),
        ),
        background: Image.network(
          imageUrl,
          fit: BoxFit.cover,
        ),
      ),
      // Optional: Add actions like icons or buttons
      actions: [
        IconButton(
          icon: Icon(Icons.search),
          onPressed: () {},
        ),
      ],
    );
  }
}

In this example:

  • expandedHeight sets the maximum height of the AppBar when it's fully expanded.
  • pinned: true ensures that the AppBar (or at least its collapsed title/toolbar) remains visible at the top of the screen even after collapsing.
  • flexibleSpace is where the magic happens. We're using FlexibleSpaceBar, a convenient widget provided by Flutter that simplifies creating common flexible space patterns, including a background image and a title that automatically fades and repositions.
  • title in FlexibleSpaceBar is automatically animated as the AppBar collapses and expands.
  • background in FlexibleSpaceBar takes our image, which will be covered by the flexibleSpace.

Integrating into a CustomScrollView

Now, let's integrate our CustomSliverAppBar into a Scaffold using a CustomScrollView for the body.


import 'package:flutter/material.dart';
// Import CustomSliverAppBar if it's in a separate file
// import 'custom_sliver_app_bar.dart'; 

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom AppBar Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          CustomSliverAppBar(
            title: 'My Awesome Title',
            imageUrl: 'https://picsum.photos/seed/picsum/800/600', // Example image URL
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Card(
                  margin: EdgeInsets.all(10),
                  child: Container(
                    height: 100,
                    alignment: Alignment.center,
                    child: Text('Item $index'),
                  ),
                );
              },
              childCount: 50, // Number of list items
            ),
          ),
        ],
      ),
    );
  }
}

In this main application:

  • Scaffold provides the basic visual structure.
  • CustomScrollView is crucial as it's the widget that orchestrates the scrolling behavior of its slivers.
  • slivers list contains our CustomSliverAppBar and a SliverList (which acts like a scrollable list view but is a sliver). As you scroll the items in the SliverList, the CustomSliverAppBar will expand and collapse.

Advanced Customizations

While FlexibleSpaceBar offers a good starting point, you can achieve even more intricate designs by directly using FlexibleSpace with widgets like Stack and LayoutBuilder. For instance, to create a parallax effect for the background image, you can use a Stack with an Image and wrap the Image in a ClipPath or Transform.translate based on the scroll offset. You can also use LayoutBuilder to dynamically change widget properties based on the AppBar's current height, allowing for complex animations and responsive layouts as the AppBar collapses.


// Example of using LayoutBuilder for dynamic title scaling
import 'package:flutter/material.dart';

class AdvancedCustomSliverAppBar extends StatelessWidget {
  final String title;
  final String imageUrl;

  const AdvancedCustomSliverAppBar({
    Key? key,
    required this.title,
    required this.imageUrl,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SliverAppBar(
      expandedHeight: 250.0,
      pinned: true,
      flexibleSpace: FlexibleSpaceBar(
        background: Image.network(
          imageUrl,
          fit: BoxFit.cover,
        ),
        // Custom title widget that scales
        title: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
            // Calculate the current collapse ratio
            // Max height is expandedHeight, min height is kToolbarHeight
            final double currentHeight = constraints.biggest.height;
            final double kToolbarHeight = Theme.of(context).platform == TargetPlatform.iOS
                ? 44.0 // iOS toolbar height
                : 56.0; // Android toolbar height

            final double collapseRatio = (currentHeight - kToolbarHeight) / (250.0 - kToolbarHeight);
            
            // Adjust font size based on collapse ratio
            final double fontSize = 16.0 + (collapseRatio * 8.0); // Scales from 16 to 24

            return Opacity(
              opacity: collapseRatio > 0.5 ? 1.0 : collapseRatio * 2, // Fade in/out
              child: Text(
                title,
                style: TextStyle(
                  color: Colors.white,
                  fontSize: fontSize,
                  fontWeight: FontWeight.bold,
                ),
              ),
            );
          },
        ),
        centerTitle: true,
      ),
    );
  }
}

Conclusion

Mastering SliverAppBar and FlexibleSpace opens up a world of possibilities for creating engaging and highly custom user interfaces in Flutter. By combining these powerful widgets with a CustomScrollView and leveraging widgets like FlexibleSpaceBar, Stack, and LayoutBuilder, developers can implement dynamic AppBars that not only look impressive but also enhance the overall user experience. Experiment with different combinations and properties to achieve the precise look and feel your application demands.

Related Articles

May 14, 2026

Building a Multi-Event Countdown Timer Widget with Reminders, Notifications, Repeat, and Custom Labels in Flutter

Building a Multi-Event Countdown Timer Widget with Reminders, Notifications, Repeat, and Custom Labels in Flutter Countdown timers are essential in many applic

May 11, 2026

Unleashing Dynamic UIs: Flutter's Animation Prowess

Unleashing Dynamic UIs: Flutter's Animation Prowess for Slide & Scale Effects Flutter's declarative UI framework, combined with its powerful animation capabilit

May 11, 2026

Building a Product Detail Page Widget in Flutter with Related Items, Review Carousel, Promo Badges, and Quick Buy

Building a Product Detail Page Widget in Flutter with Related Items, Review Carousel, Promo Badges, and Quick Buy A well-designed Product Detail Page (PDP) is