I have a very simple Flutter app with a TabBarView with two views (Tab 1 and Tab 2), one of them (Tab 1) has a ListView with many simple Text Widgets, the problem with this is that after I scroll down the ListView elements of Tab 1, if I swipe from Tab 1 to Tab 2 and finally I swipe from Tab 2 to Tab 1, the previous scroll position in the ListView of Tab 1 get lost.
Here is the code:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
late TabController controller;
@override
void initState() {
super.initState();
controller = TabController(
length: 2,
vsync: this,
);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
var tabs = const <Tab>[
Tab(icon: Icon(Icons.home), text: 'Tab 1'),
Tab(icon: Icon(Icons.account_box), text: 'Tab 2')
];
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: TabBarView(controller: controller, children: <Widget>[
ListView(children: <Widget>[
Column(children: <Widget>[
for (int i = 0; i < 48; i++) Text('Data $i'),
])
]),
const Center(child: Text('Tab 2'))
]),
bottomNavigationBar: Material(
color: Colors.deepOrange,
child: TabBar(controller: controller, tabs: tabs),
),
);
}
}
I have even separated the TabBarView childrens (Tab 1 and Tab 2) in another classes and I have noticed that the
@override
Widget build(BuildContext context) {
...
}
method of each child (Tab 1 and Tab 2) is executed every time I swipe to its container tab.
My questions are:
1.- How can I keep the scroll of the ListView even if I move from tab to tab?
2.- Is there a way to execute the
@override
Widget build(BuildContext context) {
}
method only once if I separate the TabBarView childrens (Tab 1 and Tab 2) to another classes? I mean, if I have to retrieve data when the Tab 1 and Tab 2 are created I don't want to do this every time its Tab is swiped in. That would be expensive.
3.- In general, Is there a way to prevent that a tab view (including its variables, data, etc.) be rebuilt every time I swipe to that tab?
Thank you in advance.
A scrollable, linear list of widgets. ListView is the most commonly used scrolling widget. It displays its children one after another in the scroll direction.... A scrolling view inside of which can be nested other scrolling views, with their scroll positions being intrinsically linked.
A scroll controller creates a [ScrollPosition] to manage the state-specific to an individual [Scrollable] widget. To use a custom [ScrollPosition], subclass [ScrollController] and override [createScrollPosition]. A [ScrollController] is a [Listenable].
It is simple to add scrollable on flutter. Just create SingleChildScrollView widget as a TabBarView and put all the contents as it's child.
If you give each TabBarView a PageStorageKey the scroll offset will be saved. See more info about PageStorageKey here.
To be more specific, you can use PageStorageKey with any scrollable view to keep the scrolling position, e.g.:
new ListView.builder(key: new PageStorageKey('myListView'), ...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With