Skip to content

TabBar does not scroll to the correct tab after controller is changed #115917

@absar

Description

@absar

Steps to Reproduce

  1. Execute flutter run on the code sample
  2. Press the + button to increase the number of tabs

Expected results:
TabBar should scroll to the last tab but it does not, even though that becomes the selected tab as you can see by manually scrolling to the right

Actual results:
TabBar does not scroll to the correct tab

Code sample
import 'package:flutter/material.dart';

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

class TabBarNotScrollingHome extends StatelessWidget {
  const TabBarNotScrollingHome({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const TabBarNotScrollingAfterControllerChanged(),
    );
  }
}

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

  @override
  State<TabBarNotScrollingAfterControllerChanged> createState() =>
      _TabBarNotScrollingAfterControllerChangedState();
}

class _TabBarNotScrollingAfterControllerChangedState
    extends State<TabBarNotScrollingAfterControllerChanged>
    with TickerProviderStateMixin {
  final _scrollViewController = ScrollController(initialScrollOffset: 0.0);
  TabController? _tabController;
  late List<Widget> tabPages;
  bool increaseTabs = false;
  int _totalTabs = 10;
  TabBar? _tabBar;

  @override
  void initState() {
    super.initState();
    _generateTabs();
  }

  @override
  void dispose() {
    _tabController?.dispose();
    _scrollViewController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final buildBody =
        TabBarView(controller: _tabController, children: tabPages);

    return Scaffold(
      body: NestedScrollView(
        controller: _scrollViewController,
        floatHeaderSlivers: true,
        headerSliverBuilder: buildAppBar,
        body: buildBody,
      ),
    );
  }

  List<Widget> buildAppBar(BuildContext context, bool isScrolled) {
    final addButton = IconButton(
      icon: Icon(increaseTabs ? Icons.remove : Icons.add),
      onPressed: () {
        increaseTabs = !increaseTabs;
        _generateTabs();
        setState(() {});
      },
    );

    return <Widget>[
      SliverAppBar(
        title: const Text('Press + to increase tabs =>'),
        bottom: _tabBar,
        pinned: true,
        snap: false,
        primary: true,
        actions: [addButton],
      ),
    ];
  }

  void _generateTabs() {
    if (increaseTabs) {
      _totalTabs = 15;
    } else {
      _totalTabs = 10;
    }
    _tabController = TabController(
        vsync: this, length: _totalTabs, initialIndex: _totalTabs - 1);

    _tabBar = TabBar(
      tabs: List.generate(
          _totalTabs, (index) => Center(child: Tab(text: 'Tab $index'))),
      controller: _tabController,
      isScrollable: true,
    );

    tabPages = List.generate(
      _totalTabs,
      (index) => Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Page $index', textAlign: TextAlign.center),
            const SizedBox(height: 20),
            const Text(
              'After pressing the + button to increase the tabs this page '
              'will change but the tab above will not scroll to the last Tab '
              'even though that becomes the selected tab. However if you press '
              'again to decrease the tabs it will scroll to the new last tab',
              textAlign: TextAlign.center,
              style: TextStyle(color: Colors.red),
            ),
          ],
        ),
      ),
    );
  }
}
Logs
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.3.8, on Microsoft Windows [Version 10.0.19045.2251], locale en-US)
Checking Android licenses is taking an unexpectedly long time...[√] Android toolchain - develop for Android devices (Android SDK version 32.0.0-rc1)
[√] Chrome - develop for the web
[X] Visual Studio - develop for Windows
    X Visual Studio not installed; this is necessary for Windows development.
      Download at https://visualstudio.microsoft.com/downloads/.
      Please install the "Desktop development with C++" workload, including all of its default components
[√] Android Studio (version 2021.3)
[√] IntelliJ IDEA Ultimate Edition (version 2021.1)
[√] Connected device (4 available)
[√] HTTP Host Availability

TabBarIssue.mp4

Metadata

Metadata

Assignees

Labels

f: material designflutter/packages/flutter/material repository.found in release: 3.3Found to occur in 3.3found in release: 3.6Found to occur in 3.6frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: duplicateIssue is closed as a duplicate of an existing issuer: fixedIssue is closed as already fixed in a newer version

Type

No type

Projects

Status

Done (PR merged)

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions