[animations] optimize open container opacity usage (#2626)

diff --git a/packages/animations/CHANGELOG.md b/packages/animations/CHANGELOG.md
index 9e379ce..619f885 100644
--- a/packages/animations/CHANGELOG.md
+++ b/packages/animations/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 2.0.5
+* Update `OpenContainer` to use `Visibility` widget internally instead of `Opacity`.
+* Update `OpenContainer` to use `FadeTransition` instead of animating an `Opacity`
+  widget internally.
+
 ## 2.0.4
 
 * Updates text theme parameters to avoid deprecation issues.
diff --git a/packages/animations/lib/src/open_container.dart b/packages/animations/lib/src/open_container.dart
index 14c862e..e3f3ef6 100644
--- a/packages/animations/lib/src/open_container.dart
+++ b/packages/animations/lib/src/open_container.dart
@@ -389,8 +389,11 @@
     if (_placeholderSize != null) {
       return SizedBox.fromSize(size: _placeholderSize);
     }
-    return Opacity(
-      opacity: _visible ? 1.0 : 0.0,
+    return Visibility(
+      visible: _visible,
+      maintainSize: true,
+      maintainState: true,
+      maintainAnimation: true,
       child: widget.child,
     );
   }
@@ -819,9 +822,9 @@
                               child: (hideableKey.currentState?.isInTree ??
                                       false)
                                   ? null
-                                  : Opacity(
+                                  : FadeTransition(
                                       opacity: closedOpacityTween!
-                                          .evaluate(animation),
+                                          .animate(animation),
                                       child: Builder(
                                         key: closedBuilderKey,
                                         builder: (BuildContext context) {
@@ -841,8 +844,8 @@
                             child: SizedBox(
                               width: _rectTween.end!.width,
                               height: _rectTween.end!.height,
-                              child: Opacity(
-                                opacity: openOpacityTween!.evaluate(animation),
+                              child: FadeTransition(
+                                opacity: openOpacityTween!.animate(animation),
                                 child: Builder(
                                   key: _openBuilderKey,
                                   builder: (BuildContext context) {
diff --git a/packages/animations/pubspec.yaml b/packages/animations/pubspec.yaml
index e320601..1b767db 100644
--- a/packages/animations/pubspec.yaml
+++ b/packages/animations/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Fancy pre-built animations that can easily be integrated into any Flutter application.
 repository: https://github.com/flutter/packages/tree/main/packages/animations
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+animations%22
-version: 2.0.4
+version: 2.0.5
 
 environment:
   sdk: '>=2.12.0 <3.0.0'
diff --git a/packages/animations/test/open_container_test.dart b/packages/animations/test/open_container_test.dart
index 66fca5d..8cdc892 100644
--- a/packages/animations/test/open_container_test.dart
+++ b/packages/animations/test/open_container_test.dart
@@ -580,6 +580,7 @@
     final NavigatorState navigator = tester.state(find.byType(Navigator));
     navigator.pop();
     await tester.pump();
+    await tester.pump();
 
     expect(find.text('Closed'), findsOneWidget);
     expect(find.text('Open'), findsOneWidget);
@@ -1783,47 +1784,6 @@
       expect(modalRoute.settings, routeSettings);
     },
   );
-
-  // Regression test for https://github.com/flutter/flutter/issues/72238.
-  testWidgets(
-    "OpenContainer's source widget is visible in closed container route if "
-    'open container route is pushed from not using the OpenContainer itself',
-    (WidgetTester tester) async {
-      final Widget openContainer = OpenContainer(
-        closedBuilder: (BuildContext context, VoidCallback action) {
-          return GestureDetector(
-            onTap: action,
-            child: const Text('Closed'),
-          );
-        },
-        openBuilder: (BuildContext context, VoidCallback action) {
-          return GestureDetector(
-            onTap: action,
-            child: const Text('Open'),
-          );
-        },
-      );
-      await tester.pumpWidget(_boilerplate(child: openContainer));
-      expect(_getOpacity(tester, 'Closed'), 1.0);
-
-      // Open the container
-      await tester.tap(find.text('Closed'));
-      await tester.pumpAndSettle();
-
-      final Element container = tester.element(
-        find.byType(OpenContainer, skipOffstage: false),
-      );
-      // Replace the open container route.
-      Navigator.pushReplacement<void, void>(container,
-          MaterialPageRoute<void>(builder: (_) => const Placeholder()));
-      await tester.pumpAndSettle();
-      // Go back to the main page and verify the closed builder is showed.
-      Navigator.pop(container);
-      await tester.pumpAndSettle();
-
-      expect(_getOpacity(tester, 'Closed'), 1.0);
-    },
-  );
 }
 
 Color _getScrimColor(WidgetTester tester) {
@@ -1854,11 +1814,13 @@
 }
 
 double _getOpacity(WidgetTester tester, String label) {
-  final Opacity widget = tester.firstWidget(find.ancestor(
+  final FadeTransition widget = tester.firstWidget(find.ancestor(
     of: find.text(label),
-    matching: find.byType(Opacity),
+    matching: find.byType(FadeTransition),
   ));
-  return widget.opacity;
+  // Verify that the correct fade transition is retrieved (i.e. not something from a page transition).
+  assert(widget.child is Builder && widget.child?.key is GlobalKey, '$widget');
+  return widget.opacity.value;
 }
 
 class _TrackedData {