Unverified Commit 082ad114 authored by Bruno Leroux's avatar Bruno Leroux Committed by GitHub

Fix TabController throws build scheduled during frame error (#105442)

parent 40fc5e86
......@@ -1495,15 +1495,13 @@ class _TabBarViewState extends State<TabBarView> {
}
final Duration duration = _controller!.animationDuration;
if (duration == Duration.zero) {
_pageController.jumpToPage(_currentIndex!);
return Future<void>.value();
}
final int previousIndex = _controller!.previousIndex;
if ((_currentIndex! - previousIndex).abs() == 1) {
if (duration == Duration.zero) {
_pageController.jumpToPage(_currentIndex!);
return Future<void>.value();
}
_warpUnderwayCount += 1;
await _pageController.animateToPage(_currentIndex!, duration: duration, curve: Curves.ease);
_warpUnderwayCount -= 1;
......@@ -1525,6 +1523,11 @@ class _TabBarViewState extends State<TabBarView> {
});
_pageController.jumpToPage(initialPage);
if (duration == Duration.zero) {
_pageController.jumpToPage(_currentIndex!);
return Future<void>.value();
}
await _pageController.animateToPage(_currentIndex!, duration: duration, curve: Curves.ease);
if (!mounted) {
return Future<void>.value();
......
......@@ -1191,6 +1191,51 @@ void main() {
expect(controller.indexIsChanging, false);
});
testWidgets('TabBar should not throw when animation is disabled in controller', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/102600
final List<String> tabs = <String>['A'];
Widget buildWithTabBarView() {
return boilerplate(
child: DefaultTabController(
animationDuration: Duration.zero,
length: tabs.length,
child: Column(
children: <Widget>[
TabBar(
tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
isScrollable: true,
),
Flexible(
child: TabBarView(
children: List<Widget>.generate(
tabs.length,
(int index) => Text('Tab $index'),
),
),
),
],
),
),
);
}
await tester.pumpWidget(buildWithTabBarView());
TabController controller = DefaultTabController.of(tester.element(find.text('A')))!;
expect(controller.index, 0);
tabs.add('B');
await tester.pumpWidget(buildWithTabBarView());
tabs.add('C');
await tester.pumpWidget(buildWithTabBarView());
await tester.tap(find.text('C'));
await tester.pumpAndSettle();
controller = DefaultTabController.of(tester.element(find.text('A')))!;
expect(controller.index, 2);
expect(tester.takeException(), isNull);
});
testWidgets('TabBarView skips animation when disabled in controller', (WidgetTester tester) async {
final List<String> tabs = <String>['A', 'B', 'C'];
final TabController tabController = TabController(
......
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