flutter - App bar scrolling with overlapping content in Flexible space

9,841

ScrollViews take a ScrollController which is a Listenable that notifies on scroll offset updates.

You can listen to the ScrollController and use a Stack to achieve the effect you're interested in based on the scroll offset.

Here's a quick example:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Scroll demo',
      home: new Scaffold(
        appBar: new AppBar(elevation: 0.0),
        body: new CustomScroll(),
      ),
    );
  }
}

class CustomScroll extends StatefulWidget {
  @override
  State createState() => new CustomScrollState();
}

class CustomScrollState extends State<CustomScroll> {
  ScrollController scrollController;
  double offset = 0.0;
  static const double kEffectHeight = 100.0;

  @override
  Widget build(BuildContext context) {
    return new Stack(
      alignment: AlignmentDirectional.topCenter,
      children: <Widget> [
        new Container(
          color: Colors.blue,
          height: (kEffectHeight - offset * 0.5).clamp(0.0, kEffectHeight),
        ),
        new Positioned(
          child: new Container(
            width: 200.0,
            child: new ListView.builder(
              itemCount: 100,
              itemBuilder: buildListItem,
              controller: scrollController,
            ),
          ),
        ),
      ],
    );
  }

  Widget buildListItem(BuildContext context, int index) {
    return new Container(
      color: Colors.white,
      child: new Text('Item $index')
    );
  }

  void updateOffset() {
    setState(() {
      offset = scrollController.offset;
    }); 
  }

  @override
  void initState() {
    super.initState();
    scrollController = new ScrollController();
    scrollController.addListener(updateOffset);
  }

  @override
  void dispose() {
    super.dispose();
    scrollController.removeListener(updateOffset);
  }
}
Share:
9,841
CodePLeX
Author by

CodePLeX

Updated on December 06, 2022

Comments

  • CodePLeX
    CodePLeX over 1 year

    i am trying to recreate App bar scrolling with overlapping content in Flexible space using flutter.

    the behavior is demonstrated here:

    http://karthikraj.net/2016/12/24/scrolling-behavior-for-appbars-in-android/

    I created collapsing AppBar using SliverAppBar already, using the code I pasted here, I am trying to create THIS

    i cant use Stack for it because i cant find any onScroll callback, so far i created appbar with flexibleSpace, the app bar collapse on scroll:

    Scaffold(
        body: NestedScrollView(
          headerSliverBuilder:
              (BuildContext context, bool innerBoxIsScrolled) => <Widget>[
                    SliverAppBar(
                      forceElevated: innerBoxIsScrolled,
                      pinned: true,
                      expandedHeight: 180.0,
                    ),
                  ],
          body: ListView.builder(
            itemCount: 30,
            itemBuilder: (context, index) => Text(
                  "Item $index",
                  style: Theme.of(context).textTheme.display1,
                ),
          ),
        ),
      );
    

    What i created so far

    edit: Example of what i want to create