diff --git a/packages/flutter/lib/src/widgets/expansible.dart b/packages/flutter/lib/src/widgets/expansible.dart index 356ee0940a6..41f7c7a07ce 100644 --- a/packages/flutter/lib/src/widgets/expansible.dart +++ b/packages/flutter/lib/src/widgets/expansible.dart @@ -126,6 +126,21 @@ class ExpansibleController extends ChangeNotifier { _setExpansionState(false); } + /// Convenience method for toggling the current [isExpanded] status. + /// + /// Calling this method may cause the [Expansible] to rebuild, so it may not + /// be called from a build method. + /// + /// Calling this method will notify registered listeners of this controller + /// that the expansion state has changed. + /// + /// See also: + /// + /// * [expand], which expands the [Expansible]. + /// * [collapse], which collapses the [Expansible]. + /// * [isExpanded] to check whether the [Expansible] is expanded. + void toggle() => isExpanded ? collapse() : expand(); + /// Finds the [ExpansibleController] for the closest [Expansible] instance /// that encloses the given context. /// diff --git a/packages/flutter/test/widgets/expansible_test.dart b/packages/flutter/test/widgets/expansible_test.dart index c9c03fbb9ad..4fa2c6394c3 100644 --- a/packages/flutter/test/widgets/expansible_test.dart +++ b/packages/flutter/test/widgets/expansible_test.dart @@ -511,4 +511,34 @@ void main() { controller.expand(); await tester.pump(); }); + + testWidgets('Controller can be toggled', (WidgetTester tester) async { + final controller = ExpansibleController(); + addTearDown(controller.dispose); + + await tester.pumpWidget( + MaterialApp( + home: Expansible( + controller: controller, + bodyBuilder: (BuildContext context, Animation animation) => const Text('Body'), + headerBuilder: (BuildContext context, Animation animation) => + GestureDetector(onTap: controller.toggle, child: const Text('Header')), + ), + ), + ); + + expect(find.text('Body'), findsNothing); + controller.toggle(); + await tester.pumpAndSettle(); + expect(find.text('Body'), findsOneWidget); + + controller.toggle(); + await tester.pumpAndSettle(); + expect(find.text('Body'), findsNothing); + + expect(find.text('Body'), findsNothing); + controller.toggle(); + await tester.pumpAndSettle(); + expect(find.text('Body'), findsOneWidget); + }); }