I have Material App with CustomScrollView and BottomNavigationBar, in CustomScrollView I have SliverAppBar and one page Widget (let say page1, page2 etc...) which represents BottomNavigationBar's current index, on every page Widget there is SliverList with some content

I have tried to put Keys and ScrollControllers inside CustomScrollView but it doesn't work as I expect, when navigating between pages Scroll position is initial.

class WrapperPage extends StatefulWidget {
  @override
  _WrapperPage createState() => _WrapperPage();
}

class _WrapperPage extends State<WrapperPage> {
  int _curIndex = 0;
  List<Widget> _pages;
  List<PageStorageKey> _keys;
  List<ScrollController> _ctrls;

  @override
  void initState() {
    _pages = [
      // some pages pages
    ];

    _keys = List();
    _ctrls = List();
    for (int i = 0; i < 5; ++i) {
      _keys.add(PageStorageKey('scroll$i'));
      _ctrls.add(ScrollController());
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        key: _keys[_curIndex],
        controller: _ctrls[_curIndex],
        slivers: <Widget>[SliverAppBar(), _pages[_curIndex]],
      ),
      bottomNavigationBar: BottomNavigationBar(
        onTap: (int i) {
          setState(() {
            _curIndex = i;
          });
        },
        currentIndex: _curIndex,
        items: [
          // some buttons
        ],
      ),
    );
  }
}

My goal is to save CustomScrollView's scroll state while navigating pages.

Answer

Before use PageStorageKey you must create those storage. Try this simple scratch code:

class _WrapperPage extends State<WrapperPage> {
  int _curIndex = 0;
  List<Widget> _pages;
  final bucket = PageStorageBucket();  // Create storage bucket

  @override
  void initState() {
    _pages = [];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: 
        // Wrap target widget with PageStorageBucket here.
        PageStorageBucket(
          bucket: bucket,
          child: CustomScrollView(
            // Use `runtimeType` as unique value for key
            key: PageStorageKey(_pages[_curIndex].runtimeType.toString()),
            controller: _ctrls[_curIndex],
            slivers: <Widget>[SliverAppBar(), _pages[_curIndex]],
          ),
        ),
      bottomNavigationBar: BottomNavigationBar(
        onTap: (int i) {
          setState(() {
            _curIndex = i;
          });
        },
        currentIndex: _curIndex,
        items: [
          // some buttons
        ],
      ),
    );
  }
}
  • 1
Reply Report

Warm tip !!!

This article is reproduced from Stack Exchange / Stack Overflow, please click

Trending Tags

Related Questions