letsar / flutter_sticky_header

Flutter implementation of sticky headers for sliver
MIT License
907 stars 174 forks source link

[BUG] CustomScrollView with "center" scrolls backwards #77

Open Areopagitics opened 2 years ago

Areopagitics commented 2 years ago

When using center key, the header gets stuck on the bottom. I wondering if there is a way to simply display headers for months and years indefinitely starting at a certain date in the center. There seems to be no easy way to solve this problem in Flutter.


return CustomScrollView(
        cacheExtent: 300.0,
        center: centerKey,
        anchor: 0.5,
        slivers: <Widget>[
          _rowBuilder(context, date, -1),
          SliverList(
            key: centerKey,
            delegate: SliverChildListDelegate([
              Column(
                children: [
                  Divider(),
                  Container(
                    color: Color.fromARGB(255, 174, 12, 0),
                    child: Text('data'),
                  ),
                  Divider(),
                ],
              ) 
            ]),
          ),
          _rowBuilder(context, date, 1),
        ],
      );
JChPal commented 1 year ago

I'm also stuck on this, did you find any workaround ?

I also made a full example

import 'package:flutter/material.dart';
import 'package:flutter_sticky_header/flutter_sticky_header.dart';

const customScrollViewCenterKey = ValueKey('customScrollViewCenterKey');

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

  @override
  Widget build(BuildContext context) {
    return NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return <Widget>[
          const SliverAppBar(
            title: Text('CustomScrollView center issue'),
          ),
        ];
      },
      body: CustomScrollView(
        center: customScrollViewCenterKey,
        slivers: <Widget>[
          /// before CustomScrollView center ValueKey
          SliverStickyHeader(
            header: Container(
              color: Colors.grey,
              child: const Padding(
                padding: EdgeInsets.all(24),
                child: Text('Sticky before CustomScrollView center ValueKey'),
              ),
            ),
            sliver: SliverList(
              delegate: SliverChildBuilderDelegate(
                (_, index) {
                  return Padding(
                    padding: const EdgeInsets.all(16),
                    child: Text('Child reversed $index'),
                  );
                },
                childCount: 15,
              ),
            ),
          ),

          /// CustomScrollView center ValueKey
          const SliverToBoxAdapter(
            key: customScrollViewCenterKey,
            child: Padding(
              padding: EdgeInsets.all(8.0),
              child: Text('CustomScrollView center'),
            ),
          ),

          /// After CustomScrollView center ValueKey
          SliverStickyHeader(
            header: Container(
              color: Colors.grey,
              child: const Padding(
                padding: EdgeInsets.all(24),
                child: Text('Sticky after CustomScrollView center ValueKey'),
              ),
            ),
            sliver: SliverList(
              delegate: SliverChildBuilderDelegate(
                (_, index) {
                  return Padding(
                    padding: const EdgeInsets.all(16),
                    child: Text('Child $index'),
                  );
                },
                childCount: 15,
              ),
            ),
          ),
        ],
      ),
    );
  }
}
JChPal commented 1 year ago

This issue is similar to this one : https://github.com/letsar/flutter_sticky_header/issues/11

I make it work with @charlesRmajor fork

  flutter_sticky_header:
    git:
      url: https://github.com/charlesRmajor/flutter_sticky_header
import 'package:flutter/material.dart';
import 'package:flutter_sticky_header/flutter_sticky_header.dart';

const customScrollViewCenterKey = ValueKey('customScrollViewCenterKey');

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

  @override
  Widget build(BuildContext context) {
    return NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return <Widget>[
          const SliverAppBar(
            title: Text('CustomScrollView center issue'),
          ),
        ];
      },
      body: CustomScrollView(
        center: customScrollViewCenterKey,
        slivers: <Widget>[
          /// before CustomScrollView center ValueKey
          /// ======MODIFIED CODE
          SliverStickyHeader.builder(
            reverse: true,
            /// ======MODIFIED CODE
            builder: (context, constraint) => Container(
              color: Colors.grey,
              child: const Padding(
                padding: EdgeInsets.all(24),
                child: Text('Sticky before CustomScrollView center ValueKey'),
              ),
            ),
            sliver: SliverList(
              delegate: SliverChildBuilderDelegate(
                (_, index) {
                  return Padding(
                    padding: const EdgeInsets.all(16),
                    child: Text('Child reversed $index'),
                  );
                },
                childCount: 15,
              ),
            ),
          ),

          /// CustomScrollView center ValueKey
          const SliverToBoxAdapter(
            key: customScrollViewCenterKey,
            child: Padding(
              padding: EdgeInsets.all(8.0),
              child: Text('CustomScrollView center'),
            ),
          ),

          /// After CustomScrollView center ValueKey
          SliverStickyHeader(
            header: Container(
              color: Colors.grey,
              child: const Padding(
                padding: EdgeInsets.all(24),
                child: Text('Sticky after CustomScrollView center ValueKey'),
              ),
            ),
            sliver: SliverList(
              delegate: SliverChildBuilderDelegate(
                (_, index) {
                  return Padding(
                    padding: const EdgeInsets.all(16),
                    child: Text('Child $index'),
                  );
                },
                childCount: 15,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

Do you known if the @charlesRmajor change will be integrate in your package?

Areopagitics commented 1 year ago

I've tried so many different options, I ended up going with a SingleChildScroll with a scroll controller for my particular need (but it's slow and janky) ... I'm kinda banking on this though #108289 . It was reopened ... I would recommend making some more noise over there (I think the issue describes the overall problem in Flutter). Long-term it's better to get at the root of the problem.