Skip to content

Commit e1adc96

Browse files
feat: provide a way to set the initial child's alignment (#114745)
InteractiveViewer.alignment parameter
1 parent 3cde69e commit e1adc96

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

packages/flutter/lib/src/widgets/interactive_viewer.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class InteractiveViewer extends StatefulWidget {
8787
this.scaleEnabled = true,
8888
this.scaleFactor = 200.0,
8989
this.transformationController,
90+
this.alignment,
9091
required Widget this.child,
9192
}) : assert(alignPanAxis != null),
9293
assert(panAxis != null),
@@ -141,6 +142,7 @@ class InteractiveViewer extends StatefulWidget {
141142
this.scaleEnabled = true,
142143
this.scaleFactor = 200.0,
143144
this.transformationController,
145+
this.alignment,
144146
required InteractiveViewerWidgetBuilder this.builder,
145147
}) : assert(panAxis != null),
146148
assert(builder != null),
@@ -166,6 +168,9 @@ class InteractiveViewer extends StatefulWidget {
166168
constrained = false,
167169
child = null;
168170

171+
/// The alignment of the child's origin, relative to the size of the box.
172+
final Alignment? alignment;
173+
169174
/// If set to [Clip.none], the child may extend beyond the size of the InteractiveViewer,
170175
/// but it will not receive gestures in these areas.
171176
/// Be sure that the InteractiveViewer is the desired size when using [Clip.none].
@@ -1096,6 +1101,7 @@ class _InteractiveViewerState extends State<InteractiveViewer> with TickerProvid
10961101
clipBehavior: widget.clipBehavior,
10971102
constrained: widget.constrained,
10981103
matrix: _transformationController!.value,
1104+
alignment: widget.alignment,
10991105
child: widget.child!,
11001106
);
11011107
} else {
@@ -1110,6 +1116,7 @@ class _InteractiveViewerState extends State<InteractiveViewer> with TickerProvid
11101116
childKey: _childKey,
11111117
clipBehavior: widget.clipBehavior,
11121118
constrained: widget.constrained,
1119+
alignment: widget.alignment,
11131120
matrix: matrix,
11141121
child: widget.builder!(
11151122
context,
@@ -1143,18 +1150,21 @@ class _InteractiveViewerBuilt extends StatelessWidget {
11431150
required this.clipBehavior,
11441151
required this.constrained,
11451152
required this.matrix,
1153+
required this.alignment,
11461154
});
11471155

11481156
final Widget child;
11491157
final GlobalKey childKey;
11501158
final Clip clipBehavior;
11511159
final bool constrained;
11521160
final Matrix4 matrix;
1161+
final Alignment? alignment;
11531162

11541163
@override
11551164
Widget build(BuildContext context) {
11561165
Widget child = Transform(
11571166
transform: matrix,
1167+
alignment: alignment,
11581168
child: KeyedSubtree(
11591169
key: childKey,
11601170
child: this.child,

packages/flutter/test/widgets/interactive_viewer_test.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,6 +1650,22 @@ void main() {
16501650
expect(scaleHighZoomedIn - scaleHighZoomedOut, lessThan(scaleZoomedIn - scaleZoomedOut));
16511651
});
16521652

1653+
testWidgets('alignment argument is used properly', (WidgetTester tester) async {
1654+
const Alignment alignment = Alignment.center;
1655+
1656+
await tester.pumpWidget(MaterialApp(
1657+
home: Scaffold(
1658+
body: InteractiveViewer(
1659+
alignment: alignment,
1660+
child: Container(),
1661+
),
1662+
),
1663+
));
1664+
1665+
final Transform transform = tester.firstWidget(find.byType(Transform));
1666+
expect(transform.alignment, alignment);
1667+
});
1668+
16531669
testWidgets('interactionEndFrictionCoefficient', (WidgetTester tester) async {
16541670
// Use the default interactionEndFrictionCoefficient.
16551671
final TransformationController transformationController1 = TransformationController();

0 commit comments

Comments
 (0)