Skip to content

Commit

Permalink
TabController should dispatch creation in constructor. (flutter#133952)
Browse files Browse the repository at this point in the history
  • Loading branch information
polina-c authored and Mairramer committed Oct 10, 2023
1 parent 707fccc commit 09d707c
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 3 deletions.
7 changes: 6 additions & 1 deletion packages/flutter/lib/src/material/tab_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 6,7 @@ import 'dart:math' as math;

import 'package:flutter/widgets.dart';

import '../foundation/memory_allocations.dart';
import 'constants.dart';

// Examples can assume:
Expand Down Expand Up @@ -114,7 115,11 @@ class TabController extends ChangeNotifier {
_animationController = AnimationController.unbounded(
value: initialIndex.toDouble(),
vsync: vsync,
);
) {
if (kFlutterMemoryAllocationsEnabled) {
ChangeNotifier.maybeDispatchObjectCreation(this);
}
}

// Private constructor used by `_copyWith`. This allows a new TabController to
// be created without having to create a new animationController.
Expand Down
1 change: 1 addition & 0 deletions packages/flutter/lib/src/material/tabs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 1380,7 @@ class _TabBarState extends State<TabBar> {
_controller!.removeListener(_handleTabControllerTick);
}
_controller = null;
_scrollController?.dispose();
// We don't own the _controller Animation, so it's not disposed here.
super.dispose();
}
Expand Down
6 changes: 6 additions & 0 deletions packages/flutter/test/material/page_selector_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 70,7 @@ void main() {
vsync: const TestVSync(),
length: 3,
);
addTearDown(tabController.dispose);
await tester.pumpWidget(buildFrame(tabController));

expect(tabController.index, 0);
Expand All @@ -91,6 92,7 @@ void main() {
vsync: const TestVSync(),
length: 3,
);
addTearDown(tabController.dispose);
await tester.pumpWidget(buildFrame(tabController));

expect(tabController.index, 0);
Expand Down Expand Up @@ -135,6 137,7 @@ void main() {
initialIndex: 1,
length: 3,
);
addTearDown(tabController.dispose);
await tester.pumpWidget(buildFrame(tabController));

expect(tabController.index, 1);
Expand Down Expand Up @@ -196,6 199,7 @@ void main() {
initialIndex: 1,
length: 3,
);
addTearDown(tabController.dispose);
await tester.pumpWidget(buildFrame(tabController, color: kRed, selectedColor: kBlue));

expect(tabController.index, 1);
Expand All @@ -212,6 216,7 @@ void main() {
initialIndex: 1,
length: 3,
);
addTearDown(tabController.dispose);
await tester.pumpWidget(buildFrame(tabController, indicatorSize: 16.0));

final Iterable<Element> indicatorElements = find.descendant(
Expand All @@ -233,6 238,7 @@ void main() {
initialIndex: 1,
length: 3,
);
addTearDown(tabController.dispose);

Iterable<TabPageSelectorIndicator> indicators;

Expand Down
16 changes: 16 additions & 0 deletions packages/flutter/test/material/tab_controller_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 1,16 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';

void main() {
testWidgetsWithLeakTracking('$TabController dispatches creation in constructor.', (WidgetTester widgetTester) async {
await expectLater(
await memoryEvents(() async => TabController(length: 1, vsync: const TestVSync()).dispose(), TabController),
areCreateAndDispose,
);
});
}
2 changes: 1 addition & 1 deletion packages/flutter/test/widgets/framework_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 1062,7 @@ void main() {
element.createChild(0, after: null);
});

testWidgetsWithLeakTracking('GlobalKey - re-attach child to new parents, and the old parent is deactivated(unmounted)', (WidgetTester tester) async {
testWidgets('GlobalKey - re-attach child to new parents, and the old parent is deactivated(unmounted)', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/62055
const Key key1 = GlobalObjectKey('key1');
const Key key2 = GlobalObjectKey('key2');
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter/test/widgets/scrollable_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 861,7 @@ void main() {
expect(targetMidLeftPage1, findsOneWidget);
});

testWidgetsWithLeakTracking('ensureVisible does not move TabViews', (WidgetTester tester) async {
testWidgets('ensureVisible does not move TabViews', (WidgetTester tester) async {
final TickerProvider vsync = TestTickerProvider();
final TabController controller = TabController(
length: 3,
Expand Down

0 comments on commit 09d707c

Please sign in to comment.