Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
f15295cc
Unverified
Commit
f15295cc
authored
Apr 26, 2022
by
Jonah Williams
Committed by
GitHub
Apr 26, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[framework] allow disabling image filter layer (#102085)
parent
0411a6f8
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
63 additions
and
4 deletions
+63
-4
image_filter.dart
packages/flutter/lib/src/widgets/image_filter.dart
+42
-4
image_filter_test.dart
packages/flutter/test/widgets/image_filter_test.dart
+21
-0
No files found.
packages/flutter/lib/src/widgets/image_filter.dart
View file @
f15295cc
...
...
@@ -11,6 +11,19 @@ import 'framework.dart';
/// Applies an [ImageFilter] to its child.
///
/// An image filter will always apply its filter operation to the child widget,
/// even if said filter is conceptually a "no-op", such as an ImageFilter.blur
/// with a radius of 0 or an ImageFilter.matrix with an identity matrix. Setting
/// [ImageFiltered.enabled] to `false` is a more efficient manner of disabling
/// an image filter.
///
/// The framework does not attempt to optimize out "no-op" filters because it
/// cannot tell the difference between an intentional no-op and a filter that is
/// only incidentally a no-op. Consider an ImageFilter.matrix that is animated
/// and happens to pass through the identity matrix. If the framework identified it
/// as a no-op it would drop and then recreate the layer during the animation which
/// would be more expensive than keeping it around.
///
/// {@youtube 560 315 https://www.youtube.com/watch?v=7Lftorq4i2o}
///
/// See also:
...
...
@@ -27,17 +40,27 @@ class ImageFiltered extends SingleChildRenderObjectWidget {
super
.
key
,
required
this
.
imageFilter
,
super
.
child
,
this
.
enabled
=
true
,
})
:
assert
(
imageFilter
!=
null
);
/// The image filter to apply to the child of this widget.
final
ImageFilter
imageFilter
;
/// Whether or not to apply the image filter opation to the child of this
/// widget.
///
/// Prefer setting enabled to `false` instead of creating a "no-op" filter
/// type for performance reasons.
final
bool
enabled
;
@override
RenderObject
createRenderObject
(
BuildContext
context
)
=>
_ImageFilterRenderObject
(
imageFilter
);
RenderObject
createRenderObject
(
BuildContext
context
)
=>
_ImageFilterRenderObject
(
imageFilter
,
enabled
);
@override
void
updateRenderObject
(
BuildContext
context
,
RenderObject
renderObject
)
{
(
renderObject
as
_ImageFilterRenderObject
).
imageFilter
=
imageFilter
;
(
renderObject
as
_ImageFilterRenderObject
)
..
enabled
=
enabled
..
imageFilter
=
imageFilter
;
}
@override
...
...
@@ -48,7 +71,17 @@ class ImageFiltered extends SingleChildRenderObjectWidget {
}
class
_ImageFilterRenderObject
extends
RenderProxyBox
{
_ImageFilterRenderObject
(
this
.
_imageFilter
);
_ImageFilterRenderObject
(
this
.
_imageFilter
,
this
.
_enabled
);
bool
get
enabled
=>
_enabled
;
bool
_enabled
;
set
enabled
(
bool
value
)
{
if
(
enabled
==
value
)
{
return
;
}
_enabled
=
value
;
markNeedsPaint
();
}
ImageFilter
get
imageFilter
=>
_imageFilter
;
ImageFilter
_imageFilter
;
...
...
@@ -61,11 +94,16 @@ class _ImageFilterRenderObject extends RenderProxyBox {
}
@override
bool
get
alwaysNeedsCompositing
=>
child
!=
null
;
bool
get
alwaysNeedsCompositing
=>
child
!=
null
&&
enabled
;
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
assert
(
imageFilter
!=
null
);
if
(!
enabled
)
{
layer
=
null
;
return
super
.
paint
(
context
,
offset
);
}
if
(
layer
==
null
)
{
layer
=
ImageFilterLayer
(
imageFilter:
imageFilter
);
}
else
{
...
...
packages/flutter/test/widgets/image_filter_test.dart
View file @
f15295cc
...
...
@@ -86,4 +86,25 @@ void main() {
await
pumpWithSigma
(
10.0
);
expect
(
renderObject
.
debugLayer
,
same
(
originalLayer
));
});
testWidgets
(
'Image filter - enabled and disabled'
,
(
WidgetTester
tester
)
async
{
Future
<
void
>
pumpWithEnabledStaet
(
bool
enabled
)
async
{
await
tester
.
pumpWidget
(
RepaintBoundary
(
child:
ImageFiltered
(
enabled:
enabled
,
imageFilter:
ImageFilter
.
blur
(
sigmaX:
5
,
sigmaY:
5
),
child:
const
Placeholder
(),
),
),
);
}
await
pumpWithEnabledStaet
(
false
);
expect
(
tester
.
layers
,
isNot
(
contains
(
isA
<
ImageFilterLayer
>())));
await
pumpWithEnabledStaet
(
true
);
expect
(
tester
.
layers
,
contains
(
isA
<
ImageFilterLayer
>()));
});
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment