-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Description
Is there an existing issue for this?
- I have searched the existing issues
- I have read the guide to filing a bug
Use case
I have this snippet:
Code sample
You can also checkout https://github.com/ValentinVignal/flutter_app_stable/tree/flutter/size-transition-height-factor
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(useMaterial3: true),
darkTheme: ThemeData.dark(useMaterial3: true),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var _visible = true;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ColoredBox(
color: Theme.of(context).colorScheme.secondaryContainer,
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
transitionBuilder: (child, animation) {
return SizeTransition(
sizeFactor: animation,
axis: Axis.vertical,
child: child,
);
},
child: _visible
? ColoredBox(
color: Theme.of(context).colorScheme.primaryContainer,
child: const SizedBox(
height: 200,
width: 200,
child: Center(
child: Text('Hello World'),
),
),
)
: const SizedBox(),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_visible = !_visible;
});
},
child: const Icon(Icons.add),
),
);
}
}Video
Screen.Recording.2023-09-13.at.10.02.09.PM.mov
In the video the animation is vertical. The other axis (horizontal) is stretched and uses the entire available space.
I would like my primaryContainer to be centered and only use the width of its child (200 px).
I want the secondaryContainer to shrink and be the same size as the primaryContainer (and therefore hidden).
Proposal
Add a new parameter to SizeTransition (ex: crossAxisSizeFactor)
flutter/packages/flutter/lib/src/widgets/transitions.dart
Lines 444 to 450 in 622c2b2
| const SizeTransition({ | |
| super.key, | |
| this.axis = Axis.vertical, | |
| required Animation<double> sizeFactor, | |
| this.axisAlignment = 0.0, | |
| this.child, | |
| }) : super(listenable: sizeFactor); |
class SizeTransition extends AnimatedWidget {
const SizeTransition({
// ...
+ this.crossAxisSizeFactor,
}) : super(listenable: sizeFactor);
// ...
+ final double? crossAxisSizeFactor;
}and pass it to the cross axis of the Align widget:
flutter/packages/flutter/lib/src/widgets/transitions.dart
Lines 492 to 499 in 622c2b2
| return ClipRect( | |
| child: Align( | |
| alignment: alignment, | |
| heightFactor: axis == Axis.vertical ? math.max(sizeFactor.value, 0.0) : null, | |
| widthFactor: axis == Axis.horizontal ? math.max(sizeFactor.value, 0.0) : null, | |
| child: child, | |
| ), | |
| ); |
return ClipRect(
child: Align(
alignment: alignment,
- heightFactor: axis == Axis.vertical ? math.max(sizeFactor.value, 0.0) : null,
+ heightFactor: axis == Axis.vertical ? math.max(sizeFactor.value, 0.0) : crossAxisSizeFactor,
- widthFactor: axis == Axis.horizontal ? math.max(sizeFactor.value, 0.0) : null,
+ widthFactor: axis == Axis.horizontal ? math.max(sizeFactor.value, 0.0) : crossAxisSizeFactor,
child: child,
),
);In my code sample, I would use
crossAxisSizeFactor : 1,And this gives me the output: