From e1adc96d5e01b2e5c530f99a16efcce6e86b1ac0 Mon Sep 17 00:00:00 2001 From: Pedro Massango Date: Mon, 7 Nov 2022 21:08:22 +0100 Subject: [PATCH] feat: provide a way to set the initial child's alignment (#114745) InteractiveViewer.alignment parameter --- .../lib/src/widgets/interactive_viewer.dart | 10 ++++++++++ .../test/widgets/interactive_viewer_test.dart | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/packages/flutter/lib/src/widgets/interactive_viewer.dart b/packages/flutter/lib/src/widgets/interactive_viewer.dart index 4baf68356a1b..832bdcd09566 100644 --- a/packages/flutter/lib/src/widgets/interactive_viewer.dart +++ b/packages/flutter/lib/src/widgets/interactive_viewer.dart @@ -87,6 +87,7 @@ class InteractiveViewer extends StatefulWidget { this.scaleEnabled = true, this.scaleFactor = 200.0, this.transformationController, + this.alignment, required Widget this.child, }) : assert(alignPanAxis != null), assert(panAxis != null), @@ -141,6 +142,7 @@ class InteractiveViewer extends StatefulWidget { this.scaleEnabled = true, this.scaleFactor = 200.0, this.transformationController, + this.alignment, required InteractiveViewerWidgetBuilder this.builder, }) : assert(panAxis != null), assert(builder != null), @@ -166,6 +168,9 @@ class InteractiveViewer extends StatefulWidget { constrained = false, child = null; + /// The alignment of the child's origin, relative to the size of the box. + final Alignment? alignment; + /// If set to [Clip.none], the child may extend beyond the size of the InteractiveViewer, /// but it will not receive gestures in these areas. /// Be sure that the InteractiveViewer is the desired size when using [Clip.none]. @@ -1096,6 +1101,7 @@ class _InteractiveViewerState extends State with TickerProvid clipBehavior: widget.clipBehavior, constrained: widget.constrained, matrix: _transformationController!.value, + alignment: widget.alignment, child: widget.child!, ); } else { @@ -1110,6 +1116,7 @@ class _InteractiveViewerState extends State with TickerProvid childKey: _childKey, clipBehavior: widget.clipBehavior, constrained: widget.constrained, + alignment: widget.alignment, matrix: matrix, child: widget.builder!( context, @@ -1143,6 +1150,7 @@ class _InteractiveViewerBuilt extends StatelessWidget { required this.clipBehavior, required this.constrained, required this.matrix, + required this.alignment, }); final Widget child; @@ -1150,11 +1158,13 @@ class _InteractiveViewerBuilt extends StatelessWidget { final Clip clipBehavior; final bool constrained; final Matrix4 matrix; + final Alignment? alignment; @override Widget build(BuildContext context) { Widget child = Transform( transform: matrix, + alignment: alignment, child: KeyedSubtree( key: childKey, child: this.child, diff --git a/packages/flutter/test/widgets/interactive_viewer_test.dart b/packages/flutter/test/widgets/interactive_viewer_test.dart index 512d58649514..db8a2e70fc72 100644 --- a/packages/flutter/test/widgets/interactive_viewer_test.dart +++ b/packages/flutter/test/widgets/interactive_viewer_test.dart @@ -1650,6 +1650,22 @@ void main() { expect(scaleHighZoomedIn - scaleHighZoomedOut, lessThan(scaleZoomedIn - scaleZoomedOut)); }); + testWidgets('alignment argument is used properly', (WidgetTester tester) async { + const Alignment alignment = Alignment.center; + + await tester.pumpWidget(MaterialApp( + home: Scaffold( + body: InteractiveViewer( + alignment: alignment, + child: Container(), + ), + ), + )); + + final Transform transform = tester.firstWidget(find.byType(Transform)); + expect(transform.alignment, alignment); + }); + testWidgets('interactionEndFrictionCoefficient', (WidgetTester tester) async { // Use the default interactionEndFrictionCoefficient. final TransformationController transformationController1 = TransformationController();