1

I have a Flutter app that has a BottomNavigationBar with two tabs: Home and Profile. Profile has a ListView containing the basic profile info and a GridView of posts. When switching between the two tabs, I want the scroll position of the ListView to persist. I am using PageStorageKey to do this (as pointed out by other StackOverflow answers: e.g. here) but it doesn't give the desired result as shown by this gif:

enter image description here

Two things are wrong:

  1. When returning to the Profile tab the position is recovered but it does so by scrolling to this position;
  2. When leaving the Profile tab again (without any further scrolling) it causes the ListView to begin at the top when revisiting the Profile tab again.

How do I fix these problems?

Here is the relevant code:

// Tab navigation

class NavigatorScreen extends StatefulWidget {
  @override
  _NavigatorScreenState createState() => _NavigatorScreenState();
}

class _NavigatorScreenState extends State<NavigatorScreen> {
  var _selectedIndex = 0;
  final _bucket = PageStorageBucket();

  final _screens = List<Widget>.unmodifiable([
    HomeScreen(key: PageStorageKey('home')),
    ProfileScreen(key: PageStorageKey('profile')),
  ]);

  void _onItemTapped(int index) {
    setState(() => _selectedIndex = index);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageStorage(
        child: _screens[_selectedIndex],
        bucket: _bucket,
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: 'Profile',
          ),
        ],
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
    );
  }
}
// Profile tab content

class ProfileScreen extends StatelessWidget {
  const ProfileScreen({required Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Profile'),
      ),
      body: ListView(
        key: PageStorageKey('profileList'),
        children: [
          Padding(
            padding: EdgeInsets.all(16.0),
            child: Column(
              children: [
                UserDetails(),
                PostStats(),
                PostGrid(), // GridView.builder()
              ],
            ),
          ),
        ],
      ),
    );
  }
}
Josh
  • 1,357
  • 2
  • 23
  • 45
  • Have you ever fixed this problem? I'm running into a very similar issue but yet have to find a fix for it. – adamk22 Jan 03 '23 at 22:40
  • No, though I didn't spend long on this work and haven't used Flutter since. – Josh Feb 12 '23 at 07:11

0 Answers0