Unverified Commit 234855ca authored by Hans Muller's avatar Hans Muller Committed by GitHub

Handle a TabBarView special case: last tab deleted before animation ends (#24892)

parent 3cca1a2e
......@@ -1168,9 +1168,10 @@ class _TabBarViewState extends State<TabBarView> {
if (notification is ScrollUpdateNotification && !_controller.indexIsChanging) {
if ((_pageController.page - _controller.index).abs() > 1.0) {
_controller.index = _pageController.page.floor();
_currentIndex=_controller.index;
_currentIndex = _controller.index;
}
_controller.offset = (_pageController.page - _controller.index).clamp(-1.0, 1.0);
if (_controller.length > 1)
_controller.offset = (_pageController.page - _controller.index).clamp(-1.0, 1.0);
} else if (notification is ScrollEndNotification) {
_controller.index = _pageController.page.round();
_currentIndex = _controller.index;
......
......@@ -1895,4 +1895,55 @@ void main() {
expect(find.text(AlwaysKeepAliveWidget.text, skipOffstage: false), findsOneWidget);
expect(find.text('4'), findsOneWidget);
});
testWidgets('Removing the last tab', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/24424
final List<Tab> tabs = <Tab>[const Tab(text: 'LEFT'), const Tab(text: 'RIGHT')];
Widget buildFrame(TabController controller) {
return boilerplate(
child: Container(
alignment: Alignment.topLeft,
child: Column(
children: <Widget>[
TabBar(controller: controller, tabs: tabs),
Expanded(child: TabBarView(controller: controller, children: tabs)),
]
),
),
);
}
final TabController controller1 = TabController(
vsync: const TestVSync(),
length: 2,
initialIndex: 0,
);
await tester.pumpWidget(buildFrame(controller1));
expect(controller1.index, 0);
await tester.tap(find.text('RIGHT'));
expect(controller1.index, 1);
expect(controller1.indexIsChanging, true);
// At this point the change selected tab animation hasn't completed.
// When the controller is replaced the TabBarView will see one last
// scroll notification. Since there's only one tab left, it can be
// ignored.
final TabController controller2 = TabController(
vsync: const TestVSync(),
length: 1,
initialIndex: 0,
);
tabs.removeAt(1);
await tester.pumpWidget(buildFrame(controller2));
await tester.pumpAndSettle();
expect(controller1.indexIsChanging, false);
expect(controller2.index, 0);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment