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