use FadeTransition instead of Opacity where applicable (#75110)
This commit is contained in:
@@ -758,8 +758,8 @@ class _ContextMenuRoute<T> extends PopupRoute<T> {
|
||||
children: <Widget>[
|
||||
Positioned.fromRect(
|
||||
rect: sheetRect,
|
||||
child: Opacity(
|
||||
opacity: _sheetOpacity.value,
|
||||
child: FadeTransition(
|
||||
opacity: _sheetOpacity,
|
||||
child: Transform.scale(
|
||||
alignment: getSheetAlignment(_contextMenuLocation),
|
||||
scale: sheetScale,
|
||||
@@ -1028,8 +1028,8 @@ class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> with T
|
||||
return Transform.scale(
|
||||
alignment: _ContextMenuRoute.getSheetAlignment(widget.contextMenuLocation),
|
||||
scale: _sheetScaleAnimation.value,
|
||||
child: Opacity(
|
||||
opacity: _sheetOpacityAnimation.value,
|
||||
child: FadeTransition(
|
||||
opacity: _sheetOpacityAnimation,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1211,8 +1211,8 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Opacity(
|
||||
opacity: _opacityAnimation.value,
|
||||
return FadeTransition(
|
||||
opacity: _opacityAnimation,
|
||||
child: Transform(
|
||||
transform: Matrix4.rotationZ(_orientationOffset + _orientationAnimation.value)
|
||||
..setTranslationRaw(0.0, _arrowIconBaselineOffset, 0.0),
|
||||
|
||||
@@ -373,8 +373,8 @@ class _HelperErrorState extends State<_HelperError> with SingleTickerProviderSta
|
||||
assert(widget.helperText != null);
|
||||
return Semantics(
|
||||
container: true,
|
||||
child: Opacity(
|
||||
opacity: 1.0 - _controller.value,
|
||||
child: FadeTransition(
|
||||
opacity: Tween<double>(begin: 1.0, end: 0.0).animate(_controller),
|
||||
child: Text(
|
||||
widget.helperText!,
|
||||
style: widget.helperStyle,
|
||||
@@ -391,8 +391,8 @@ class _HelperErrorState extends State<_HelperError> with SingleTickerProviderSta
|
||||
return Semantics(
|
||||
container: true,
|
||||
liveRegion: true,
|
||||
child: Opacity(
|
||||
opacity: _controller.value,
|
||||
child: FadeTransition(
|
||||
opacity: _controller,
|
||||
child: FractionalTranslation(
|
||||
translation: Tween<Offset>(
|
||||
begin: const Offset(0.0, -0.25),
|
||||
@@ -441,8 +441,8 @@ class _HelperErrorState extends State<_HelperError> with SingleTickerProviderSta
|
||||
if (widget.errorText != null) {
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
Opacity(
|
||||
opacity: 1.0 - _controller.value,
|
||||
FadeTransition(
|
||||
opacity: Tween<double>(begin: 1.0, end: 0.0).animate(_controller),
|
||||
child: _helper,
|
||||
),
|
||||
_buildError(),
|
||||
@@ -454,8 +454,8 @@ class _HelperErrorState extends State<_HelperError> with SingleTickerProviderSta
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
_buildHelper(),
|
||||
Opacity(
|
||||
opacity: _controller.value,
|
||||
FadeTransition(
|
||||
opacity: _controller,
|
||||
child: _error,
|
||||
),
|
||||
],
|
||||
|
||||
@@ -573,6 +573,7 @@ class _RailDestination extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
} else {
|
||||
final Animation<double> labelFadeAnimation = extendedTransitionAnimation.drive(CurveTween(curve: const Interval(0.0, 0.25)));
|
||||
content = Padding(
|
||||
padding: padding ?? EdgeInsets.zero,
|
||||
child: ConstrainedBox(
|
||||
@@ -587,9 +588,9 @@ class _RailDestination extends StatelessWidget {
|
||||
heightFactor: 1.0,
|
||||
widthFactor: extendedTransitionAnimation.value,
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
child: Opacity(
|
||||
child: FadeTransition(
|
||||
alwaysIncludeSemantics: true,
|
||||
opacity: _extendedLabelFadeValue(),
|
||||
opacity: labelFadeAnimation,
|
||||
child: styledLabel,
|
||||
),
|
||||
),
|
||||
@@ -604,6 +605,8 @@ class _RailDestination extends StatelessWidget {
|
||||
case NavigationRailLabelType.selected:
|
||||
final double appearingAnimationValue = 1 - _positionAnimation.value;
|
||||
final double verticalPadding = lerpDouble(_verticalDestinationPaddingNoLabel, _verticalDestinationPaddingWithLabel, appearingAnimationValue)!;
|
||||
final Interval interval = selected ? const Interval(0.25, 0.75) : const Interval(0.75, 1.0);
|
||||
final Animation<double> labelFadeAnimation = destinationAnimation.drive(CurveTween(curve: interval));
|
||||
content = Container(
|
||||
constraints: BoxConstraints(
|
||||
minWidth: minWidth,
|
||||
@@ -621,9 +624,9 @@ class _RailDestination extends StatelessWidget {
|
||||
alignment: Alignment.topCenter,
|
||||
heightFactor: appearingAnimationValue,
|
||||
widthFactor: 1.0,
|
||||
child: Opacity(
|
||||
child: FadeTransition(
|
||||
alwaysIncludeSemantics: true,
|
||||
opacity: selected ? _normalLabelFadeInValue() : _normalLabelFadeOutValue(),
|
||||
opacity: labelFadeAnimation,
|
||||
child: styledLabel,
|
||||
),
|
||||
),
|
||||
@@ -679,28 +682,6 @@ class _RailDestination extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
double _normalLabelFadeInValue() {
|
||||
if (destinationAnimation.value < 0.25) {
|
||||
return 0;
|
||||
} else if (destinationAnimation.value < 0.75) {
|
||||
return (destinationAnimation.value - 0.25) * 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
double _normalLabelFadeOutValue() {
|
||||
if (destinationAnimation.value > 0.75) {
|
||||
return (destinationAnimation.value - 0.75) * 4.0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
double _extendedLabelFadeValue() {
|
||||
return extendedTransitionAnimation.value < 0.25 ? extendedTransitionAnimation.value * 4.0 : 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines the behavior of the labels of a [NavigationRail].
|
||||
|
||||
@@ -596,8 +596,8 @@ class _PopupMenu<T> extends StatelessWidget {
|
||||
return AnimatedBuilder(
|
||||
animation: route.animation!,
|
||||
builder: (BuildContext context, Widget? child) {
|
||||
return Opacity(
|
||||
opacity: opacity.evaluate(route.animation!),
|
||||
return FadeTransition(
|
||||
opacity: opacity.animate(route.animation!),
|
||||
child: Material(
|
||||
shape: route.shape ?? popupMenuTheme.shape,
|
||||
color: route.color ?? popupMenuTheme.color,
|
||||
|
||||
@@ -547,8 +547,8 @@ class _HeroFlight {
|
||||
left: offsets.left,
|
||||
child: IgnorePointer(
|
||||
child: RepaintBoundary(
|
||||
child: Opacity(
|
||||
opacity: _heroOpacity.value,
|
||||
child: FadeTransition(
|
||||
opacity: _heroOpacity,
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -117,7 +117,7 @@ void checkBackgroundBoxHeight(WidgetTester tester, double height) {
|
||||
|
||||
void checkOpacity(WidgetTester tester, Finder finder, double opacity) {
|
||||
expect(
|
||||
tester.renderObject<RenderAnimatedOpacity>(
|
||||
tester.firstRenderObject<RenderAnimatedOpacity>(
|
||||
find.ancestor(
|
||||
of: finder,
|
||||
matching: find.byType(FadeTransition),
|
||||
|
||||
@@ -2331,14 +2331,23 @@ Finder _opacityAboveLabel(String text) {
|
||||
}
|
||||
|
||||
// Only valid when labelType != all.
|
||||
double _labelOpacity(WidgetTester tester, String text) {
|
||||
final Opacity opacityWidget = tester.widget<Opacity>(
|
||||
double? _labelOpacity(WidgetTester tester, String text) {
|
||||
// We search for both Opacity and FadeTransition since in some
|
||||
// cases opacity is animated, in other it's not.
|
||||
final Iterable<Opacity> opacityWidgets = tester.widgetList<Opacity>(find.ancestor(
|
||||
of: find.text(text),
|
||||
matching: find.byType(Opacity),
|
||||
));
|
||||
if (opacityWidgets.isNotEmpty)
|
||||
return opacityWidgets.single.opacity;
|
||||
|
||||
final FadeTransition fadeTransitionWidget = tester.widget<FadeTransition>(
|
||||
find.ancestor(
|
||||
of: find.text(text),
|
||||
matching: find.byType(Opacity),
|
||||
),
|
||||
matching: find.byType(FadeTransition),
|
||||
).first, // first because there's also a FadeTransition from the MaterialPageRoute, which is up the tree
|
||||
);
|
||||
return opacityWidget.opacity;
|
||||
return fadeTransitionWidget.opacity.value;
|
||||
}
|
||||
|
||||
Material _railMaterial(WidgetTester tester) {
|
||||
|
||||
@@ -1182,7 +1182,7 @@ Future<void> main() async {
|
||||
bool isVisible = true;
|
||||
node.visitAncestorElements((Element ancestor) {
|
||||
final RenderObject r = ancestor.renderObject!;
|
||||
if (r is RenderOpacity && r.opacity == 0) {
|
||||
if (r is RenderAnimatedOpacity && r.opacity.value == 0) {
|
||||
isVisible = false;
|
||||
return false;
|
||||
}
|
||||
@@ -2920,12 +2920,12 @@ Future<void> main() async {
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
final ScrollController controller = ScrollController();
|
||||
|
||||
RenderOpacity? findRenderOpacity() {
|
||||
RenderAnimatedOpacity? findRenderAnimatedOpacity() {
|
||||
AbstractNode? parent = tester.renderObject(find.byType(Placeholder));
|
||||
while (parent is RenderObject && parent is! RenderOpacity) {
|
||||
while (parent is RenderObject && parent is! RenderAnimatedOpacity) {
|
||||
parent = parent.parent;
|
||||
}
|
||||
return parent is RenderOpacity ? parent : null;
|
||||
return parent is RenderAnimatedOpacity ? parent : null;
|
||||
}
|
||||
|
||||
await tester.pumpWidget(
|
||||
@@ -2977,14 +2977,14 @@ Future<void> main() async {
|
||||
// Starts Hero animation and scroll animation almost simultaneously.
|
||||
// Scroll to make the Hero invisible.
|
||||
await tester.pump();
|
||||
expect(findRenderOpacity()?.opacity, anyOf(isNull, 1.0));
|
||||
expect(findRenderAnimatedOpacity()?.opacity.value, anyOf(isNull, 1.0));
|
||||
|
||||
// In this frame the Hero animation finds out the toHero is not paintable,
|
||||
// and starts fading.
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
|
||||
expect(findRenderOpacity()?.opacity, lessThan(1.0));
|
||||
expect(findRenderAnimatedOpacity()?.opacity.value, lessThan(1.0));
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
// The Hero on the new route should be invisible.
|
||||
|
||||
Reference in New Issue
Block a user