fluttercandies / extended_nested_scroll_view

extended nested scroll view to fix following issues. 1.pinned sliver header issue 2.inner scrollables in tabview sync issue 3.pull to refresh is not work. 4.do without ScrollController in NestedScrollView's body
MIT License
592 stars 119 forks source link

floatHeaderSlivers: true #38

Closed comerc closed 4 years ago

comerc commented 4 years ago

Please, release floatHeaderSlivers: true

https://github.com/flutter/flutter/pull/59187

zmtzawqlp commented 4 years ago

It seems that the change is not only in nested_scroll_view.dart.

comerc commented 4 years ago

I just checked. NestedScrollView works great!

Updated files: ~/flutter/packages/flutter/lib/src/widgets/nested_scroll_view.dart ~/flutter/packages/flutter/lib/src/rendering/sliver_persistent_header.dart ~/flutter/packages/flutter/lib/src/rendering/viewport.dart ~/flutter/packages/flutter/lib/src/widgets/viewport.dart

Demo:

Widget build(BuildContext context) {
  return Scaffold(
    body: NestedScrollView(
      // Setting floatHeaderSlivers to true is required in order to float
      // the outer slivers over the inner scrollable.
      floatHeaderSlivers: true,
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return <Widget>[
          SliverAppBar(
            title: const Text('Floating Nested SliverAppBar'),
            floating: true,
            expandedHeight: 200.0,
            forceElevated: innerBoxIsScrolled,
          ),
        ];
      },
      body: ListView.builder(
        padding: const EdgeInsets.all(8),
        itemCount: 30,
        itemBuilder: (BuildContext context, int index) {
          return Container(
            height: 50,
            child: Center(child: Text('Item $index')),
          );
        }
      )
    )
  );
}
zmtzawqlp commented 4 years ago

thanks, but I wonder if it works when it has multiple SliverPersistentHeader. i will do more testing for this

comerc commented 4 years ago

I checked it with SliverPersistentHeader. NestedScrollView works!

Demo:

import 'package:flutter/material.dart';

class NestedScrollViewScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final statusBarHeight = MediaQuery.of(context).padding.top;
    final tabBarHeight = 48.0;
    return Scaffold(
        body: NestedScrollView(
            // Setting floatHeaderSlivers to true is required in order to float
            // the outer slivers over the inner scrollable.
            floatHeaderSlivers: true,
            headerSliverBuilder:
                (BuildContext context, bool innerBoxIsScrolled) {
              return <Widget>[
                SliverPersistentHeader(
                  pinned: true,
                  delegate: _CommonSliverPersistentHeaderDelegate(
                    child: Container(),
                    height: statusBarHeight,
                  ),
                ),
                SliverPersistentHeader(
                  delegate: _CommonSliverPersistentHeaderDelegate(
                      child: Container(
                          color: Colors.orange[50],
                          child: Center(child: Text('Title'))),
                      height: kToolbarHeight),
                ),
                SliverPersistentHeader(
                  pinned: true,
                  delegate: _CommonSliverPersistentHeaderDelegate(
                    child: Container(
                        color: Colors.white,
                        child: Center(child: Text('TabBar'))),
                    height: tabBarHeight,
                  ),
                ),
                //   SliverAppBar(
                //     title: const Text('Floating Nested SliverAppBar'),
                //     floating: true,
                //     expandedHeight: 200.0,
                //     forceElevated: innerBoxIsScrolled,
                //   ),
              ];
            },
            body: ListView.builder(
                padding: const EdgeInsets.all(8),
                itemCount: 30,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    height: 50,
                    child: Center(child: Text('Item $index')),
                  );
                })));
  }
}

class _CommonSliverPersistentHeaderDelegate
    extends SliverPersistentHeaderDelegate {
  _CommonSliverPersistentHeaderDelegate({this.child, this.height});

  final Widget child;
  final double height;

  @override
  double get minExtent => height;

  @override
  double get maxExtent => height;

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return child;
  }

  @override
  bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
    //print("shouldRebuild---------------");
    return oldDelegate != this;
  }
}
comerc commented 4 years ago

Please see demo-video:

https://youtu.be/MHfjBjoZypA

zmtzawqlp commented 4 years ago

does it work for multiple SliverPersistentHeader which floating: true?

comerc commented 4 years ago

Yes! Its works too.

zmtzawqlp commented 4 years ago

ready for pub, close this if it has no problem

comerc commented 4 years ago

I thank you for your cooperation!