diff --git a/packages/two_dimensional_scrollables/CHANGELOG.md b/packages/two_dimensional_scrollables/CHANGELOG.md index 0bcac837523..34bcde5cae5 100644 --- a/packages/two_dimensional_scrollables/CHANGELOG.md +++ b/packages/two_dimensional_scrollables/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.2 + +* Fixes a bug where the TreeView would not update correctly when the animation duration is zero. + ## 0.3.1 * Adds generics to the callbacks and builders of TreeView. diff --git a/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart b/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart index ba6c4632c40..a3ba1bd218f 100644 --- a/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart +++ b/packages/two_dimensional_scrollables/lib/src/tree_view/tree.dart @@ -886,6 +886,15 @@ class _TreeViewState extends State> if (widget.onNodeToggle != null) { widget.onNodeToggle!(node); } + + // If animation is disabled or duration is zero, skip the animation + // and update the active nodes immediately. This ensures the tree + // is updated correctly when the node's children are no longer active. + if (widget.toggleAnimationStyle?.duration == Duration.zero) { + _unpackActiveNodes(); + return; + } + final AnimationController controller = _currentAnimationForParent[node]?.controller ?? AnimationController( diff --git a/packages/two_dimensional_scrollables/pubspec.yaml b/packages/two_dimensional_scrollables/pubspec.yaml index 45845c7afe0..6fbafb4d9a3 100644 --- a/packages/two_dimensional_scrollables/pubspec.yaml +++ b/packages/two_dimensional_scrollables/pubspec.yaml @@ -1,6 +1,6 @@ name: two_dimensional_scrollables description: Widgets that scroll using the two dimensional scrolling foundation. -version: 0.3.1 +version: 0.3.2 repository: https://github.com/flutter/packages/tree/main/packages/two_dimensional_scrollables issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+two_dimensional_scrollables%22+ diff --git a/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart b/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart index a1790879fe9..6177ce33707 100644 --- a/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart +++ b/packages/two_dimensional_scrollables/test/tree_view/tree_test.dart @@ -718,6 +718,102 @@ void main() { expect(treeView.treeNodeBuilder, isA>()); expect(treeView.treeRowBuilder, isA>()); }); + + testWidgets( + 'TreeViewNode should expand/collapse correctly when the animation duration is set to zero.', + (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/154292 + final TreeViewController controller = TreeViewController(); + final List> tree = >[ + TreeViewNode('First'), + TreeViewNode( + 'Second', + children: >[ + TreeViewNode( + 'alpha', + children: >[ + TreeViewNode('uno'), + TreeViewNode('dos'), + TreeViewNode('tres'), + ], + ), + TreeViewNode('beta'), + TreeViewNode('kappa'), + ], + ), + TreeViewNode( + 'Third', + expanded: true, + children: >[ + TreeViewNode('gamma'), + TreeViewNode('delta'), + TreeViewNode('epsilon'), + ], + ), + TreeViewNode('Fourth'), + ]; + + await tester.pumpWidget(MaterialApp( + home: TreeView( + tree: tree, + controller: controller, + toggleAnimationStyle: AnimationStyle( + curve: Curves.easeInOut, + duration: Duration.zero, + ), + treeNodeBuilder: ( + BuildContext context, + TreeViewNode node, + AnimationStyle animationStyle, + ) { + final Widget child = GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () => controller.toggleNode(node), + child: TreeView.defaultTreeNodeBuilder( + context, + node, + animationStyle, + ), + ); + + return child; + }, + ), + )); + + expect(find.text('First'), findsOneWidget); + expect(find.text('Second'), findsOneWidget); + expect(find.text('Third'), findsOneWidget); + expect(find.text('Fourth'), findsOneWidget); + expect(find.text('alpha'), findsNothing); + expect(find.text('beta'), findsNothing); + expect(find.text('kappa'), findsNothing); + expect(find.text('gamma'), findsOneWidget); + expect(find.text('delta'), findsOneWidget); + expect(find.text('epsilon'), findsOneWidget); + expect(find.text('uno'), findsNothing); + expect(find.text('dos'), findsNothing); + expect(find.text('tres'), findsNothing); + + await tester.tap(find.text('Second')); + await tester.pumpAndSettle(); + + expect(find.text('alpha'), findsOneWidget); + + await tester.tap(find.text('alpha')); + await tester.pumpAndSettle(); + + expect(find.text('uno'), findsOneWidget); + expect(find.text('dos'), findsOneWidget); + expect(find.text('tres'), findsOneWidget); + + await tester.tap(find.text('alpha')); + await tester.pumpAndSettle(); + + expect(find.text('uno'), findsNothing); + expect(find.text('dos'), findsNothing); + expect(find.text('tres'), findsNothing); + }); }); group('TreeViewport', () {