Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flutter - App bar scrolling with overlapping content in Flexible space

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

like image 921
CodePLeX Avatar asked Jul 22 '18 20:07

CodePLeX


People also ask

How do you make the scrollable app bar in flutter?

Basic implementation You need to pass it on ScrollAppBar 's controller and inside your ListView , also in controller property. Without this, you'll get an ordinary App Bar. Now, you can use the ScrollAppBar widget in a Scaffold widget, and attach ScrollController instance in your scrollable main widget.

How do I hide the app bar when scrolling in flutter?

Hidden Appbar is the Appbar, when we are scrolling the main body of the Application, the Appbar also scrolled and goes to hidden. There is no need for extra packages of adding, we simply going to use NestedScrollView Widget for the same.

How do I use flexible space in AppBar flutter?

flexibleSpace field, a flexible space bar expands and contracts as the app scrolls so that the AppBar reaches from the top of the app to the top of the scrolling contents of the app. When using SliverAppBar. flexibleSpace, the SliverAppBar. expandedHeight must be large enough to accommodate the SliverAppBar.


1 Answers

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);
  }
}
like image 119
amir Avatar answered Sep 20 '22 06:09

amir