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