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),
),
),
),
],
),
),
);
}
}