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
5import 'package:flutter/rendering.dart';
6
7import 'basic.dart';
8import 'framework.dart';
9import '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.
40class 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