1 | // Copyright 2014 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | import 'package:flutter/rendering.dart'; |
6 | |
7 | import 'basic.dart'; |
8 | import 'framework.dart'; |
9 | import 'image.dart'; |
10 | |
11 | /// A sliver widget that paints a [Decoration] either before or after its child |
12 | /// paints. |
13 | /// |
14 | /// Unlike [DecoratedBox], this widget expects its child to be a sliver, and |
15 | /// must be placed in a widget that expects a sliver. |
16 | /// |
17 | /// If the child sliver has infinite [SliverGeometry.scrollExtent], then we only |
18 | /// draw the decoration down to the bottom [SliverGeometry.cacheExtent], and |
19 | /// it is necessary to ensure that the bottom border does not creep |
20 | /// above the top of the bottom cache. This can happen if the bottom has a |
21 | /// border radius larger than the extent of the cache area. |
22 | /// |
23 | /// Commonly used with [BoxDecoration]. |
24 | /// |
25 | /// The [child] is not clipped. To clip a child to the shape of a particular |
26 | /// [ShapeDecoration], consider using a [ClipPath] widget. |
27 | /// |
28 | /// {@tool dartpad} |
29 | /// This sample shows a radial gradient that draws a moon on a night sky: |
30 | /// |
31 | /// ** See code in examples/api/lib/widgets/sliver/decorated_sliver.0.dart ** |
32 | /// {@end-tool} |
33 | /// |
34 | /// See also: |
35 | /// |
36 | /// * [DecoratedBox], the version of this class that works with RenderBox widgets. |
37 | /// * [Decoration], which you can extend to provide other effects with |
38 | /// [DecoratedSliver]. |
39 | /// * [CustomPaint], another way to draw custom effects from the widget layer. |
40 | class DecoratedSliver extends SingleChildRenderObjectWidget { |
41 | /// Creates a widget that paints a [Decoration]. |
42 | /// |
43 | /// By default the decoration paints behind the child. |
44 | const DecoratedSliver({ |
45 | super.key, |
46 | required this.decoration, |
47 | this.position = DecorationPosition.background, |
48 | Widget? sliver, |
49 | }) : super(child: sliver); |
50 | |
51 | /// What decoration to paint. |
52 | /// |
53 | /// Commonly a [BoxDecoration]. |
54 | final Decoration decoration; |
55 | |
56 | /// Whether to paint the box decoration behind or in front of the child. |
57 | final DecorationPosition position; |
58 | |
59 | @override |
60 | RenderDecoratedSliver createRenderObject(BuildContext context) { |
61 | return RenderDecoratedSliver( |
62 | decoration: decoration, |
63 | position: position, |
64 | configuration: createLocalImageConfiguration(context), |
65 | ); |
66 | } |
67 | |
68 | @override |
69 | void updateRenderObject(BuildContext context, RenderDecoratedSliver renderObject) { |
70 | renderObject |
71 | ..decoration = decoration |
72 | ..position = position |
73 | ..configuration = createLocalImageConfiguration(context); |
74 | } |
75 | |
76 | @override |
77 | void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
78 | super.debugFillProperties(properties); |
79 | final String label; |
80 | switch (position) { |
81 | case DecorationPosition.background: |
82 | label = 'bg' ; |
83 | case DecorationPosition.foreground: |
84 | label = 'fg' ; |
85 | } |
86 | properties.add(EnumProperty<DecorationPosition>('position' , position, level: DiagnosticLevel.hidden)); |
87 | properties.add(DiagnosticsProperty<Decoration>(label, decoration)); |
88 | } |
89 | } |
90 | |