[framework] introduce repaint boundary in Opacity widgets (#101601)
This commit is contained in:
parent
2d9e171870
commit
6def1596cd
@ -242,7 +242,7 @@ class Directionality extends InheritedWidget {
|
|||||||
/// opacity.
|
/// opacity.
|
||||||
/// * [Image], which can directly provide a partially transparent image with
|
/// * [Image], which can directly provide a partially transparent image with
|
||||||
/// much less performance hit.
|
/// much less performance hit.
|
||||||
class Opacity extends SingleChildRenderObjectWidget {
|
class Opacity extends StatelessWidget {
|
||||||
/// Creates a widget that makes its child partially transparent.
|
/// Creates a widget that makes its child partially transparent.
|
||||||
///
|
///
|
||||||
/// The [opacity] argument must not be null and must be between 0.0 and 1.0
|
/// The [opacity] argument must not be null and must be between 0.0 and 1.0
|
||||||
@ -251,10 +251,10 @@ class Opacity extends SingleChildRenderObjectWidget {
|
|||||||
Key? key,
|
Key? key,
|
||||||
required this.opacity,
|
required this.opacity,
|
||||||
this.alwaysIncludeSemantics = false,
|
this.alwaysIncludeSemantics = false,
|
||||||
Widget? child,
|
this.child,
|
||||||
}) : assert(opacity != null && opacity >= 0.0 && opacity <= 1.0),
|
}) : assert(opacity != null && opacity >= 0.0 && opacity <= 1.0),
|
||||||
assert(alwaysIncludeSemantics != null),
|
assert(alwaysIncludeSemantics != null),
|
||||||
super(key: key, child: child);
|
super(key: key);
|
||||||
|
|
||||||
/// The fraction to scale the child's alpha value.
|
/// The fraction to scale the child's alpha value.
|
||||||
///
|
///
|
||||||
@ -278,6 +278,44 @@ class Opacity extends SingleChildRenderObjectWidget {
|
|||||||
/// would otherwise contribute relevant semantics.
|
/// would otherwise contribute relevant semantics.
|
||||||
final bool alwaysIncludeSemantics;
|
final bool alwaysIncludeSemantics;
|
||||||
|
|
||||||
|
/// The widget below this widget in the tree.
|
||||||
|
///
|
||||||
|
/// {@macro flutter.widgets.ProxyWidget.child}
|
||||||
|
final Widget? child;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return _Opacity(
|
||||||
|
opacity: opacity,
|
||||||
|
alwaysIncludeSemantics: alwaysIncludeSemantics,
|
||||||
|
child: RepaintBoundary(
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
super.debugFillProperties(properties);
|
||||||
|
properties.add(DoubleProperty('opacity', opacity));
|
||||||
|
properties.add(FlagProperty('alwaysIncludeSemantics', value: alwaysIncludeSemantics, ifTrue: 'alwaysIncludeSemantics'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The backing implementation of [Opacity].
|
||||||
|
class _Opacity extends SingleChildRenderObjectWidget {
|
||||||
|
const _Opacity({
|
||||||
|
Key? key,
|
||||||
|
required this.opacity,
|
||||||
|
this.alwaysIncludeSemantics = false,
|
||||||
|
Widget? child,
|
||||||
|
}) : assert(opacity != null && opacity >= 0.0 && opacity <= 1.0),
|
||||||
|
assert(alwaysIncludeSemantics != null),
|
||||||
|
super(key: key, child: child);
|
||||||
|
|
||||||
|
final double opacity;
|
||||||
|
final bool alwaysIncludeSemantics;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
RenderOpacity createRenderObject(BuildContext context) {
|
RenderOpacity createRenderObject(BuildContext context) {
|
||||||
return RenderOpacity(
|
return RenderOpacity(
|
||||||
@ -292,13 +330,6 @@ class Opacity extends SingleChildRenderObjectWidget {
|
|||||||
..opacity = opacity
|
..opacity = opacity
|
||||||
..alwaysIncludeSemantics = alwaysIncludeSemantics;
|
..alwaysIncludeSemantics = alwaysIncludeSemantics;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
|
||||||
super.debugFillProperties(properties);
|
|
||||||
properties.add(DoubleProperty('opacity', opacity));
|
|
||||||
properties.add(FlagProperty('alwaysIncludeSemantics', value: alwaysIncludeSemantics, ifTrue: 'alwaysIncludeSemantics'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A widget that applies a mask generated by a [Shader] to its child.
|
/// A widget that applies a mask generated by a [Shader] to its child.
|
||||||
|
@ -1759,7 +1759,9 @@ class _AnimatedOpacityState extends ImplicitlyAnimatedWidgetState<AnimatedOpacit
|
|||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
opacity: _opacityAnimation,
|
opacity: _opacityAnimation,
|
||||||
alwaysIncludeSemantics: widget.alwaysIncludeSemantics,
|
alwaysIncludeSemantics: widget.alwaysIncludeSemantics,
|
||||||
child: widget.child,
|
child: RepaintBoundary(
|
||||||
|
child: widget.child,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -483,7 +483,7 @@ class SizeTransition extends AnimatedWidget {
|
|||||||
/// * [Opacity], which does not animate changes in opacity.
|
/// * [Opacity], which does not animate changes in opacity.
|
||||||
/// * [AnimatedOpacity], which animates changes in opacity without taking an
|
/// * [AnimatedOpacity], which animates changes in opacity without taking an
|
||||||
/// explicit [Animation] argument.
|
/// explicit [Animation] argument.
|
||||||
class FadeTransition extends SingleChildRenderObjectWidget {
|
class FadeTransition extends StatelessWidget {
|
||||||
/// Creates an opacity transition.
|
/// Creates an opacity transition.
|
||||||
///
|
///
|
||||||
/// The [opacity] argument must not be null.
|
/// The [opacity] argument must not be null.
|
||||||
@ -491,9 +491,9 @@ class FadeTransition extends SingleChildRenderObjectWidget {
|
|||||||
Key? key,
|
Key? key,
|
||||||
required this.opacity,
|
required this.opacity,
|
||||||
this.alwaysIncludeSemantics = false,
|
this.alwaysIncludeSemantics = false,
|
||||||
Widget? child,
|
this.child,
|
||||||
}) : assert(opacity != null),
|
}) : assert(opacity != null),
|
||||||
super(key: key, child: child);
|
super(key: key);
|
||||||
|
|
||||||
/// The animation that controls the opacity of the child.
|
/// The animation that controls the opacity of the child.
|
||||||
///
|
///
|
||||||
@ -513,6 +513,44 @@ class FadeTransition extends SingleChildRenderObjectWidget {
|
|||||||
/// would otherwise contribute relevant semantics.
|
/// would otherwise contribute relevant semantics.
|
||||||
final bool alwaysIncludeSemantics;
|
final bool alwaysIncludeSemantics;
|
||||||
|
|
||||||
|
/// The widget below this widget in the tree.
|
||||||
|
///
|
||||||
|
/// {@macro flutter.widgets.ProxyWidget.child}
|
||||||
|
final Widget? child;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return _FadeTransition(
|
||||||
|
opacity: opacity,
|
||||||
|
alwaysIncludeSemantics: alwaysIncludeSemantics,
|
||||||
|
child: RepaintBoundary(
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
super.debugFillProperties(properties);
|
||||||
|
properties.add(DiagnosticsProperty<Animation<double>>('opacity', opacity));
|
||||||
|
properties.add(FlagProperty('alwaysIncludeSemantics', value: alwaysIncludeSemantics, ifTrue: 'alwaysIncludeSemantics'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The backing implementation of a [FadeTransition].
|
||||||
|
class _FadeTransition extends SingleChildRenderObjectWidget {
|
||||||
|
const _FadeTransition({
|
||||||
|
Key? key,
|
||||||
|
required this.opacity,
|
||||||
|
this.alwaysIncludeSemantics = false,
|
||||||
|
Widget? child,
|
||||||
|
}) : assert(opacity != null),
|
||||||
|
super(key: key, child: child);
|
||||||
|
|
||||||
|
final Animation<double> opacity;
|
||||||
|
|
||||||
|
final bool alwaysIncludeSemantics;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
RenderAnimatedOpacity createRenderObject(BuildContext context) {
|
RenderAnimatedOpacity createRenderObject(BuildContext context) {
|
||||||
return RenderAnimatedOpacity(
|
return RenderAnimatedOpacity(
|
||||||
@ -527,13 +565,6 @@ class FadeTransition extends SingleChildRenderObjectWidget {
|
|||||||
..opacity = opacity
|
..opacity = opacity
|
||||||
..alwaysIncludeSemantics = alwaysIncludeSemantics;
|
..alwaysIncludeSemantics = alwaysIncludeSemantics;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
|
||||||
super.debugFillProperties(properties);
|
|
||||||
properties.add(DiagnosticsProperty<Animation<double>>('opacity', opacity));
|
|
||||||
properties.add(FlagProperty('alwaysIncludeSemantics', value: alwaysIncludeSemantics, ifTrue: 'alwaysIncludeSemantics'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Animates the opacity of a sliver widget.
|
/// Animates the opacity of a sliver widget.
|
||||||
|
@ -951,7 +951,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await expectLater(
|
await expectLater(
|
||||||
find.byType(RepaintBoundary).last,
|
find.byType(RepaintBoundary).first,
|
||||||
matchesGoldenFile('nav_bar_test.large_title.png'),
|
matchesGoldenFile('nav_bar_test.large_title.png'),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -128,6 +128,8 @@ void main() {
|
|||||||
' RepaintBoundary-[GlobalKey#00000]\n'
|
' RepaintBoundary-[GlobalKey#00000]\n'
|
||||||
' IgnorePointer\n'
|
' IgnorePointer\n'
|
||||||
' AnimatedBuilder\n'
|
' AnimatedBuilder\n'
|
||||||
|
' RepaintBoundary\n'
|
||||||
|
' _FadeTransition\n'
|
||||||
' FadeTransition\n'
|
' FadeTransition\n'
|
||||||
' FractionalTranslation\n'
|
' FractionalTranslation\n'
|
||||||
' SlideTransition\n'
|
' SlideTransition\n'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user