0

I have this code which consists of tabs, and in each tab there's a list of items, I'm using CustomScrollView because I have some other details in header.

My question is: How to save scroll position for every tab? without using NestedScrollView because it'll complicated the code, and without using SliverFillRemaining because it's make the scroll works in bad way?

Note: you can try the code here: https://dartpad.dartlang.org/?id=5c57ea1afdbde5d6f69143423b800d6a

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
  List<String> items = List.generate(50, (index) => 'Item # $index');
  List<String> tabs = List.generate(7, (index) => 'Tab # $index');
  List<ScrollController> scrollController = List.generate(7, (index) => ScrollController());
  late TabController tabController;

  @override
  void initState() {
    super.initState();
    tabController = TabController(length: tabs.length, vsync: this);
    tabController.addListener(() {
      if (!tabController.indexIsChanging) setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    print('index: ${tabController.index} , tab: ${tabs[tabController.index]} , '
        'scrollController: ${scrollController[tabController.index]}');
    return MaterialApp(
      home: Scaffold(
        body: CustomScrollView(
          // to remember scroll position, but it's not working!
          key: PageStorageKey<String>('tab${tabController.index}'),
          controller: scrollController[tabController.index],
          slivers: [
            SliverAppBar(
              pinned: true,
              expandedHeight: 200,
              flexibleSpace: const FlexibleSpaceBar(
                collapseMode: CollapseMode.pin,
                titlePadding: EdgeInsets.only(bottom: 60),
                title: Text('Title'),
              ),
              bottom: TabBar(
                controller: tabController,
                isScrollable: true,
                tabs: tabs.map((tab) => Tab(child: Text(tab))).toList(),
              ),
            ),
            SliverList(
              // to remember scroll position, but it's not working!
              key: PageStorageKey<String>('list${tabController.index}'),
              delegate: SliverChildBuilderDelegate(
                childCount: items.length,
                (context, index) => Container(
                  margin: const EdgeInsets.all(8),
                  padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 32),
                  color: Colors.grey.withOpacity(0.2),
                  child: Text('${tabs[tabController.index]} ${items[index]}', textScaleFactor: 2),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Khalid
  • 31
  • 5

0 Answers0