2

Issue

Watch the video on Imgur : Imgur

You can watch the video here as well : Cloudinary

As you can see in the video that the scroll position isn't being maintained. It looks like the pages are scrolling all together.

Basic App Structure

I am using NestedScrollView with SliverAppBar and TabBarView to acheive simple scrolling effect. The tabbar shows different pages which in turn use Provider for state management and I am returning CustomScrollView.

Home Page :

    DefaultTabController(
          length: 3,
          child: Scaffold(
            body: NestedScrollView(
              headerSliverBuilder: (context, innerBoxIsScrolled) => [
                SliverAppBar(
                  floating: true,
                  pinned: true,
                  snap: true,
                  forceElevated: true,
                  title: Text('Title'),
                  bottom: TabBar(
                    tabs: [
                      Tab(
                        icon: Icon(Icons.extension_rounded),
                      ),
                      Tab(
                        icon: Icon(Icons.folder_rounded),
                      ),
                      Tab(
                        icon: Icon(Icons.settings_rounded),
                      )
                    ],
                  ),
                ),
              ],
              body: TabBarView(
                children: [
                  PageStorage(
                    bucket: _bucket,
                    child: ExtensionsView(
                      key: PageStorageKey('extensions_view'),
                    ),
                  ),
                  PageStorage(
                    bucket: _bucket,
                    child: VideosView(
                      key: PageStorageKey('videos_view'),
                    ),
                  ),
                  PageStorage(
                    bucket: _bucket,
                    child: SettingsView(
                      key: PageStorageKey('settings'),
                    ),
                  ),
                ],
              ),
            ),
          ),
        );

TabbarView Pages

return ViewModelBuilder<ExtensionsViewModel>.reactive(
      viewModelBuilder: () => ExtensionsViewModel(),
      onModelReady: (model) => model.fetchData(),
      builder: (context, model, child) => CustomScrollView(
        slivers: [
          if (model.isBusy)
            SliverList(
              delegate: SliverChildBuilderDelegate(
                (context, index) {
                  return FilledVideoCard.loading(
                    borderRadius: BorderRadius.zero,
                  );
                },
                childCount: 3,
              ),
            )
          else
            SliverList(
              delegate: SliverChildBuilderDelegate(
                (context, index) {
                  final data = model.extensions[index];
                  return FilledVideoCard(
                    key: ObjectKey(data),
                    title: data.title,
                    price: data.price,
                    date: data.date,
                    image: data.image,
                    tags: [data.version, ...data.tags],
                    borderRadius: BorderRadius.zero,
                    onTap: () {},
                  );
                },
                childCount: model.extensions.length,
              ),
            ),
        ],
      ),
    )

Note :

  1. In all tabbarview pages, I am using AutomaticKeepAliveClientMixin to make sure that page is created only once.
  2. In all tabbarview pages, I am returning CutomScrollView.

What I have tried so far

I have tried different methods to maintain scroll position inside the tabbarview.

  1. PageStorageKey('page')
  2. PageStorageKey('page') withPageStorage()
  3. ScrollController with CustomScrollView
  4. Passing PageStorageKey to CustomScrollView through widget constructor

I tried all above to preserve scroll position but as you can see in the video that the scroll position is not maintained. The scroll position is only conserved if the CustomScrollView is added directly to the TabbarView. But in my case, the CustomScrollView is nested in a stateful widget that uses Stacked (Provide) for state management & scroll position in not maintained.

However if I assign a controller to CustomScrollView in each page, then I loose the SliverAppBar's scroll animation.

So is there any way to maintain state in the nested scrollview??

0 Answers0