7

Problem:

Scroll position of the tabView is not restored correctly when one of the tabView is scrolled to the top (revealing the sliverAppBar). The other tabView will also scrolled to the top (losing its previous scroll position).

  • This problem will not show up if normal app bar is used (not collapsible app bar)
  • This problem only shows up when the tabView is scrolled to top

Question:

How to preserve the scroll position of the tabView when using collapsible app bar (sliverAppBar)?

Code:

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new DefaultTabController(
      length: 2,
      child: Scaffold(
        body: NestedScrollView(
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
            return <Widget>[
              SliverAppBar(
                title: Text('Example'),
                pinned: true,
                floating: true,
                forceElevated: innerBoxIsScrolled,
                bottom: TabBar(
                  tabs: <Widget>[
                    Tab(text: 'One',),
                    Tab(text: 'Two'),
                  ],
                ),
              ),
            ];
          },
          body: TabBarView(
            children: <Widget>[
              Center(
                key: PageStorageKey<String>('one'),
                child: ListView.builder(
                  itemBuilder: (BuildContext context, int index) {
                    return new ListTile(
                      title: new Text('One Item $index'),
                    );
                  },
                ),
              ),
              Center(
                key: PageStorageKey<String>('two'),
                child: ListView.builder(
                  itemBuilder: (BuildContext context, int index) {
                    return new ListTile(
                      title: new Text('Two Item $index'),
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      )
    );
  }
}
thesecretmaster
  • 1,950
  • 1
  • 27
  • 39

1 Answers1

0

This is actually a known issue and still open. Although there is a workaround as mentioned in this thread:

Here's a workaround that uses extended_nested_scroll_view package. With this, I haven't encountered any issues (at least for now). So until flutter fixes this issue, this workaround seems sufficient. Only tested on Android.

The basic gist of it is:

  • Use NestedScrollView from the package extended_nested_scroll_view
  • Wrap each tab view in a StatefulWidget with AutomaticKeepAliveClientMixin and wantKeepAlive => true
  • Inside that StatefulWidget(s), wrap the scrollable content in NestedScrollViewInnerScrollPositionKeyWidget
  • Key values used in innerScrollPositionKeyBuilder and NestedScrollViewInnerScrollPositionKeyWidget must match.
MαπμQμαπkγVπ.0
  • 5,887
  • 1
  • 27
  • 65