Commit 9cb12086 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Samples for BoxDecoration and some related classes (#9902)

parent 9935b307
...@@ -122,7 +122,7 @@ class BorderRadius { ...@@ -122,7 +122,7 @@ class BorderRadius {
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
if (identical(this, other)) if (identical(this, other))
return true; return true;
if (other is! BorderRadius) if (runtimeType != other.runtimeType)
return false; return false;
final BorderRadius typedOther = other; final BorderRadius typedOther = other;
return topLeft == typedOther.topLeft && return topLeft == typedOther.topLeft &&
...@@ -152,6 +152,37 @@ enum BorderStyle { ...@@ -152,6 +152,37 @@ enum BorderStyle {
} }
/// A side of a border of a box. /// A side of a border of a box.
///
/// A [Border] consists of four [BorderSide] objects: [Border.top],
/// [Border.left], [Border.right], and [Border.bottom].
///
/// ## Sample code
///
/// This sample shows how [BorderSide] objects can be used in a [Container], via
/// a [BoxDecoration] and a [Border], to decorate some [Text]. In this example,
/// the text has a thick bar above it that is light blue, and a thick bar below
/// it that is a darker shade of blue.
///
/// ```dart
/// new Container(
/// padding: new EdgeInsets.all(8.0),
/// decoration: new BoxDecoration(
/// border: new Border(
/// top: new BorderSide(width: 16.0, color: Colors.lightBlue.shade50),
/// bottom: new BorderSide(width: 16.0, color: Colors.lightBlue.shade900),
/// ),
/// ),
/// child: new Text('Flutter in the sky', textAlign: TextAlign.center),
/// ),
/// ```
///
/// See also:
///
/// * [Border], which uses [BorderSide] objects to represent its sides.
/// * [BoxDecoration], which optionally takes a [Border] object.
/// * [TableBorder], which extends [Border] to have two more sides
/// ([TableBorder.horizontalInside] and [TableBorder.verticalInside]), both
/// of which are also [BorderSide] objects.
@immutable @immutable
class BorderSide { class BorderSide {
/// Creates the side of a border. /// Creates the side of a border.
...@@ -228,7 +259,7 @@ class BorderSide { ...@@ -228,7 +259,7 @@ class BorderSide {
return new BorderSide( return new BorderSide(
color: Color.lerp(colorA, colorB, t), color: Color.lerp(colorA, colorB, t),
width: ui.lerpDouble(a.width, b.width, t), width: ui.lerpDouble(a.width, b.width, t),
style: BorderStyle.solid style: BorderStyle.solid,
); );
} }
...@@ -236,7 +267,7 @@ class BorderSide { ...@@ -236,7 +267,7 @@ class BorderSide {
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
if (identical(this, other)) if (identical(this, other))
return true; return true;
if (other is! BorderSide) if (runtimeType != other.runtimeType)
return false; return false;
final BorderSide typedOther = other; final BorderSide typedOther = other;
return color == typedOther.color && return color == typedOther.color &&
...@@ -252,6 +283,58 @@ class BorderSide { ...@@ -252,6 +283,58 @@ class BorderSide {
} }
/// A border of a box, comprised of four sides. /// A border of a box, comprised of four sides.
///
/// The sides are represented by [BorderSide] objects.
///
/// ## Sample code
///
/// ```dart
/// // All four borders the same, two-pixel wide solid white:
/// const Border.all(width: 2.0, color: const Color(0xFFFFFFFF))
/// ```
///
/// ```dart
/// // The border for a material design divider:
/// new Border(bottom: new BorderSide(color: Theme.of(context).dividerColor))
/// ```
///
/// ```dart
/// // A 1990s-era "OK" button:
/// new Container(
/// decoration: const BoxDecoration(
/// border: const Border(
/// top: const BorderSide(width: 1.0, color: const Color(0xFFFFFFFFFF)),
/// left: const BorderSide(width: 1.0, color: const Color(0xFFFFFFFFFF)),
/// right: const BorderSide(width: 1.0, color: const Color(0xFFFF000000)),
/// bottom: const BorderSide(width: 1.0, color: const Color(0xFFFF000000)),
/// ),
/// ),
/// child: new Container(
/// padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0),
/// decoration: const BoxDecoration(
/// border: const Border(
/// top: const BorderSide(width: 1.0, color: const Color(0xFFFFDFDFDF)),
/// left: const BorderSide(width: 1.0, color: const Color(0xFFFFDFDFDF)),
/// right: const BorderSide(width: 1.0, color: const Color(0xFFFF7F7F7F)),
/// bottom: const BorderSide(width: 1.0, color: const Color(0xFFFF7F7F7F)),
/// ),
/// color: const Color(0xFFBFBFBF),
/// ),
/// child: const Text(
/// 'OK',
/// textAlign: TextAlign.center,
/// style: const TextStyle(color: const Color(0xFF000000))
/// ),
/// ),
/// ),
/// ```
///
/// See also:
///
/// * [BoxDecoration], which uses this class to describe its edge decoration.
/// * [BorderSide], which is used to describe each side of the box.
/// * [Theme], from the material layer, which can be queried to obtain appropriate colors
/// to use for borders in a material app, as shown in the "divider" sample above.
@immutable @immutable
class Border { class Border {
/// Creates a border. /// Creates a border.
...@@ -261,14 +344,16 @@ class Border { ...@@ -261,14 +344,16 @@ class Border {
this.top: BorderSide.none, this.top: BorderSide.none,
this.right: BorderSide.none, this.right: BorderSide.none,
this.bottom: BorderSide.none, this.bottom: BorderSide.none,
this.left: BorderSide.none this.left: BorderSide.none,
}); });
/// A uniform border with all sides the same color and width. /// A uniform border with all sides the same color and width.
///
/// The sides default to black solid borders, one logical pixel wide.
factory Border.all({ factory Border.all({
Color color: const Color(0xFF000000), Color color: const Color(0xFF000000),
double width: 1.0, double width: 1.0,
BorderStyle style: BorderStyle.solid BorderStyle style: BorderStyle.solid,
}) { }) {
final BorderSide side = new BorderSide(color: color, width: width, style: style); final BorderSide side = new BorderSide(color: color, width: width, style: style);
return new Border(top: side, right: side, bottom: side, left: side); return new Border(top: side, right: side, bottom: side, left: side);
...@@ -286,12 +371,16 @@ class Border { ...@@ -286,12 +371,16 @@ class Border {
/// The left side of this border. /// The left side of this border.
final BorderSide left; final BorderSide left;
/// The widths of the sides of this border represented as an EdgeInsets. /// The widths of the sides of this border represented as an [EdgeInsets].
///
/// This can be used, for example, with a [Padding] widget to inset a box by
/// the size of these borders.
EdgeInsets get dimensions { EdgeInsets get dimensions {
return new EdgeInsets.fromLTRB(left.width, top.width, right.width, bottom.width); return new EdgeInsets.fromLTRB(left.width, top.width, right.width, bottom.width);
} }
/// Whether all four sides of the border are identical. /// Whether all four sides of the border are identical. Uniform borders are
/// typically more efficient to paint.
bool get isUniform { bool get isUniform {
assert(top != null); assert(top != null);
assert(right != null); assert(right != null);
...@@ -319,7 +408,7 @@ class Border { ...@@ -319,7 +408,7 @@ class Border {
return true; return true;
} }
/// Creates a new border with the widths of this border multiplied by [t]. /// Creates a new border with the widths of this border multiplied by `t`.
Border scale(double t) { Border scale(double t) {
return new Border( return new Border(
top: top.copyWith(width: t * top.width), top: top.copyWith(width: t * top.width),
...@@ -330,6 +419,9 @@ class Border { ...@@ -330,6 +419,9 @@ class Border {
} }
/// Linearly interpolate between two borders. /// Linearly interpolate between two borders.
///
/// If a border is null, it is treated as having four [BorderSide.none]
/// borders.
static Border lerp(Border a, Border b, double t) { static Border lerp(Border a, Border b, double t) {
if (a == null && b == null) if (a == null && b == null)
return null; return null;
...@@ -345,24 +437,35 @@ class Border { ...@@ -345,24 +437,35 @@ class Border {
); );
} }
/// Paints the border within the given rect on the given canvas. /// Paints the border within the given [Rect] on the given [Canvas].
///
/// Uniform borders are more efficient to paint than more complex borders.
///
/// You can provide a [BoxShape] to draw the border on. If the shape in
/// [BoxShape.circle], there is the requirement that the border [isUniform].
///
/// If you specify a rectangular box shape (BoxShape.rectangle), then you may
/// specify a [BorderRadius]. If a border radius is specified, there is the
/// requirement that the border [isUniform].
void paint(Canvas canvas, Rect rect, { void paint(Canvas canvas, Rect rect, {
BoxShape shape: BoxShape.rectangle, BoxShape shape: BoxShape.rectangle,
BorderRadius borderRadius: null BorderRadius borderRadius: null,
}) { }) {
if (isUniform) { if (isUniform) {
if (borderRadius != null) { if (borderRadius != null) {
assert(shape == BoxShape.rectangle, 'A borderRadius can only be given for rectangular boxes.');
_paintBorderWithRadius(canvas, rect, borderRadius); _paintBorderWithRadius(canvas, rect, borderRadius);
return; return;
} }
if (shape == BoxShape.circle) { if (shape == BoxShape.circle) {
assert(borderRadius == null);
_paintBorderWithCircle(canvas, rect); _paintBorderWithCircle(canvas, rect);
return; return;
} }
} }
assert(borderRadius == null); // TODO(abarth): Support non-uniform rounded borders. assert(borderRadius == null, 'A borderRadius can only be given for uniform borders.'); // TODO(abarth): Support non-uniform rounded borders.
assert(shape == BoxShape.rectangle); // TODO(ianh): Support non-uniform borders on circles. assert(shape == BoxShape.rectangle, 'A border can only be drawn as a circle if it is uniform.'); // TODO(ianh): Support non-uniform borders on circles.
assert(top != null); assert(top != null);
assert(right != null); assert(right != null);
...@@ -483,7 +586,7 @@ class Border { ...@@ -483,7 +586,7 @@ class Border {
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
if (identical(this, other)) if (identical(this, other))
return true; return true;
if (other.runtimeType != runtimeType) if (runtimeType != other.runtimeType)
return false; return false;
final Border typedOther = other; final Border typedOther = other;
return top == typedOther.top && return top == typedOther.top &&
...@@ -598,7 +701,7 @@ class BoxShadow { ...@@ -598,7 +701,7 @@ class BoxShadow {
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
if (identical(this, other)) if (identical(this, other))
return true; return true;
if (other is! BoxShadow) if (runtimeType != other.runtimeType)
return false; return false;
final BoxShadow typedOther = other; final BoxShadow typedOther = other;
return color == typedOther.color && return color == typedOther.color &&
...@@ -615,6 +718,9 @@ class BoxShadow { ...@@ -615,6 +718,9 @@ class BoxShadow {
} }
/// A 2D gradient. /// A 2D gradient.
///
/// This is an interface that allows [LinearGradient] and [RadialGradient]
/// classes to be used interchangeably in [BoxDecoration]s.
@immutable @immutable
abstract class Gradient { abstract class Gradient {
/// Abstract const constructor. This constructor enables subclasses to provide /// Abstract const constructor. This constructor enables subclasses to provide
...@@ -626,6 +732,52 @@ abstract class Gradient { ...@@ -626,6 +732,52 @@ abstract class Gradient {
} }
/// A 2D linear gradient. /// A 2D linear gradient.
///
/// This class is used by [BoxDecoration] to represent gradients. This abstracts
/// out the arguments to the [new ui.Gradient.linear] constructor from the
/// `dart:ui` library.
///
/// A gradient has two anchor points, [begin] and [end]. The [begin] point
/// corresponds to 0.0, and the [end] point corresponds to 1.0. These points are
/// expressed in fractions, so that the same gradient can be reused with varying
/// sized boxes without changing the parameters. (This contrasts with [new
/// ui.Gradient.linear], whose arguments are expressed in logical pixels.)
///
/// The [colors] are described by a list of [Color] objects. There must be at
/// least two colors. If there are more than two, a [stops] list must be
/// provided. It must have the same length as [colors], and specifies the
/// position of each color stop between 0.0 and 1.0.
///
/// The region of the canvas before [begin] and after [end] is colored according
/// to [tileMode].
///
/// Typically this class is used with [BoxDecoration], which does the painting.
/// To use a [LinearGradient] to paint on a canvas directly, see [createShader].
///
/// ## Sample code
///
/// This sample draws a picture that looks like vertical window shades by having
/// a [Container] display a [BoxDecoration] with a [LinearGradient].
///
/// ```dart
/// new Container(
/// decoration: new BoxDecoration(
/// gradient: new LinearGradient(
/// begin: FractionalOffset.topLeft,
/// end: new FractionalOffset(0.1, 0.0), // 10% of the width, so there are ten blinds.
/// colors: [const Color(0xFFFFFFEE), const Color(0xFF999999)], // whitish to gray
/// tileMode: TileMode.repeated, // repeats the gradient over the canvas
/// ),
/// ),
/// ),
/// ```
///
/// See also:
///
/// * [RadialGradient], which displays a gradient in concentric circles, and
/// has an example which shows a different way to use [Gradient] objects.
/// * [BoxDecoration], which can take a [LinearGradient] in its
/// [BoxDecoration.gradient] property.
class LinearGradient extends Gradient { class LinearGradient extends Gradient {
/// Creates a linear graident. /// Creates a linear graident.
/// ///
...@@ -636,7 +788,7 @@ class LinearGradient extends Gradient { ...@@ -636,7 +788,7 @@ class LinearGradient extends Gradient {
this.end: FractionalOffset.centerRight, this.end: FractionalOffset.centerRight,
this.colors, this.colors,
this.stops, this.stops,
this.tileMode: TileMode.clamp this.tileMode: TileMode.clamp,
}) : assert(begin != null), }) : assert(begin != null),
assert(end != null), assert(end != null),
assert(colors != null), assert(colors != null),
...@@ -660,17 +812,32 @@ class LinearGradient extends Gradient { ...@@ -660,17 +812,32 @@ class LinearGradient extends Gradient {
/// The colors the gradient should obtain at each of the stops. /// The colors the gradient should obtain at each of the stops.
/// ///
/// If [stops] is non-null, this list must have the same length as [stops]. /// If [stops] is non-null, this list must have the same length as [stops]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// This list must have at least two colors in it (otherwise, it's not a
/// gradient!).
final List<Color> colors; final List<Color> colors;
/// A list of values from 0.0 to 1.0 that denote fractions of the vector from /// A list of values from 0.0 to 1.0 that denote fractions of the vector from
/// start to end. /// start to end.
/// ///
/// If non-null, this list must have the same length as [colors]. Otherwise /// If non-null, this list must have the same length as [colors]. If
/// the colors are distributed evenly between [begin] and [end]. /// [colors] has more than two colors, [stops] must be non-null.
///
/// If the first value is not 0.0, then a stop with position 0.0 and a color
/// equal to the first color in [colors] is implied.
///
/// If the last value is not 1.0, then a stop with position 1.0 and a color
/// equal to the last color in [colors] is implied.
///
/// The values in the [stops] list must be in ascending order. If a value in
/// the [stops] list is less than an earlier value in the list, then its value
/// is assumed to equal the previous value.
final List<double> stops; final List<double> stops;
/// How this gradient should tile the plane. /// How this gradient should tile the plane beyond in the region before
/// [begin] and after [end].
final TileMode tileMode; final TileMode tileMode;
@override @override
...@@ -682,7 +849,8 @@ class LinearGradient extends Gradient { ...@@ -682,7 +849,8 @@ class LinearGradient extends Gradient {
); );
} }
/// Returns a new [LinearGradient] with its properties scaled by the given factor. /// Returns a new [LinearGradient] with its properties scaled by the given
/// factor.
LinearGradient scale(double factor) { LinearGradient scale(double factor) {
return new LinearGradient( return new LinearGradient(
begin: begin, begin: begin,
...@@ -696,8 +864,10 @@ class LinearGradient extends Gradient { ...@@ -696,8 +864,10 @@ class LinearGradient extends Gradient {
/// Linearly interpolate between two [LinearGradient]s. /// Linearly interpolate between two [LinearGradient]s.
/// ///
/// If either gradient is null, this function linearly interpolates from a /// If either gradient is null, this function linearly interpolates from a
/// a gradient that matches the other gradient in begin, end, stops and /// a gradient that matches the other gradient in [begin], [end], [stops] and
/// tileMode and with the same colors but transparent. /// [tileMode] and with the same [colors] but transparent.
///
/// If neither gradient is null, they must have the same number of [colors].
static LinearGradient lerp(LinearGradient a, LinearGradient b, double t) { static LinearGradient lerp(LinearGradient a, LinearGradient b, double t) {
if (a == null && b == null) if (a == null && b == null)
return null; return null;
...@@ -712,11 +882,11 @@ class LinearGradient extends Gradient { ...@@ -712,11 +882,11 @@ class LinearGradient extends Gradient {
assert(a.colors.length == b.colors.length); assert(a.colors.length == b.colors.length);
assert(a.stops == null || b.stops == null || a.stops.length == b.stops.length); assert(a.stops == null || b.stops == null || a.stops.length == b.stops.length);
final List<Color> interpolatedColors = <Color>[]; final List<Color> interpolatedColors = <Color>[];
for (int i = 0; i < a.colors.length; i++) for (int i = 0; i < a.colors.length; i += 1)
interpolatedColors.add(Color.lerp(a.colors[i], b.colors[i], t)); interpolatedColors.add(Color.lerp(a.colors[i], b.colors[i], t));
List<double> interpolatedStops; List<double> interpolatedStops;
if (a.stops != null && b.stops != null) { if (a.stops != null && b.stops != null) {
for (int i = 0; i < a.stops.length; i++) for (int i = 0; i < a.stops.length; i += 1)
interpolatedStops.add(ui.lerpDouble(a.stops[i], b.stops[i], t)); interpolatedStops.add(ui.lerpDouble(a.stops[i], b.stops[i], t));
} else { } else {
interpolatedStops = a.stops ?? b.stops; interpolatedStops = a.stops ?? b.stops;
...@@ -734,7 +904,7 @@ class LinearGradient extends Gradient { ...@@ -734,7 +904,7 @@ class LinearGradient extends Gradient {
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
if (identical(this, other)) if (identical(this, other))
return true; return true;
if (other is! LinearGradient) if (runtimeType != other.runtimeType)
return false; return false;
final LinearGradient typedOther = other; final LinearGradient typedOther = other;
if (begin != typedOther.begin || if (begin != typedOther.begin ||
...@@ -772,6 +942,56 @@ class LinearGradient extends Gradient { ...@@ -772,6 +942,56 @@ class LinearGradient extends Gradient {
} }
/// A 2D radial gradient. /// A 2D radial gradient.
///
/// This class is used by [BoxDecoration] to represent gradients. This abstracts
/// out the arguments to the [new ui.Gradient.radial] constructor from the
/// `dart:ui` library.
///
/// A gradient has a [center] and a [radius]. The [center] point corresponds to
/// 0.0, and the ring at [radius] from the center corresponds to 1.0. These
/// lengths are expressed in fractions, so that the same gradient can be reused
/// with varying sized boxes without changing the parameters. (This contrasts
/// with [new ui.Gradient.radial], whose arguments are expressed in logical
/// pixels.)
///
/// The [colors] are described by a list of [Color] objects. There must be at
/// least two colors. If there are more than two, a [stops] list must be
/// provided. It must have the same length as [colors], and specifies the
/// position of each color stop between 0.0 and 1.0.
///
/// The region of the canvas beyond [radius] from the [center] is colored
/// according to [tileMode].
///
/// Typically this class is used with [BoxDecoration], which does the painting.
/// To use a [RadialGradient] to paint on a canvas directly, see [createShader].
///
/// ## Sample code
///
/// ```dart
/// // This gradient looks like a sun in a blue sky.
/// var gradient = new RadialGradient(
/// center: const FractionalOffset(0.7, 0.2), // near the top right
/// radius: 0.2,
/// colors: [
/// const Color(0xFFFFFF00), // yellow sun
/// const Color(0xFF0099FF), // blue sky
/// ],
/// stops: [0.4, 1.0],
/// );
/// // rect is the area we are painting over
/// var paint = new Paint()
/// ..shader = gradient.createShader(rect);
/// canvas.drawRect(rect, paint);
/// ```
///
/// See also:
///
/// * [LinearGradient], which displays a gradient in parallel lines, and has an
/// example which shows a different way to use [Gradient] objects.
/// * [BoxDecoration], which can take a [RadialGradient] in its
/// [BoxDecoration.gradient] property.
/// * [CustomPainter], which shows how to use the above sample code in a custom
/// painter.
class RadialGradient extends Gradient { class RadialGradient extends Gradient {
/// Creates a radial graident. /// Creates a radial graident.
/// ///
...@@ -782,7 +1002,7 @@ class RadialGradient extends Gradient { ...@@ -782,7 +1002,7 @@ class RadialGradient extends Gradient {
this.radius: 0.5, this.radius: 0.5,
this.colors, this.colors,
this.stops, this.stops,
this.tileMode: TileMode.clamp this.tileMode: TileMode.clamp,
}); });
/// The center of the gradient, as an offset into the unit square /// The center of the gradient, as an offset into the unit square
...@@ -802,7 +1022,11 @@ class RadialGradient extends Gradient { ...@@ -802,7 +1022,11 @@ class RadialGradient extends Gradient {
/// The colors the gradient should obtain at each of the stops. /// The colors the gradient should obtain at each of the stops.
/// ///
/// If [stops] is non-null, this list must have the same length as [stops]. /// If [stops] is non-null, this list must have the same length as [stops]. If
/// [colors] has more than two colors, [stops] must be non-null.
///
/// This list must have at least two colors in it (otherwise, it's not a
/// gradient!).
final List<Color> colors; final List<Color> colors;
/// A list of values from 0.0 to 1.0 that denote concentric rings. /// A list of values from 0.0 to 1.0 that denote concentric rings.
...@@ -810,12 +1034,22 @@ class RadialGradient extends Gradient { ...@@ -810,12 +1034,22 @@ class RadialGradient extends Gradient {
/// The rings are centered at [center] and have a radius equal to the value of /// The rings are centered at [center] and have a radius equal to the value of
/// the stop times [radius]. /// the stop times [radius].
/// ///
/// If non-null, this list must have the same length as [colors]. Otherwise /// If non-null, this list must have the same length as [colors]. If
/// the colors are distributed evenly between the [center] and the ring at /// [colors] has more than two colors, [stops] must be non-null.
/// [radius]. ///
/// If the first value is not 0.0, then a stop with position 0.0 and a color
/// equal to the first color in [colors] is implied.
///
/// If the last value is not 1.0, then a stop with position 1.0 and a color
/// equal to the last color in [colors] is implied.
///
/// The values in the [stops] list must be in ascending order. If a value in
/// the [stops] list is less than an earlier value in the list, then its value
/// is assumed to equal the previous value.
final List<double> stops; final List<double> stops;
/// How this gradient should tile the plane. /// How this gradient should tile the plane beyond the outer ring at [radius]
/// pixels from the [center].
final TileMode tileMode; final TileMode tileMode;
@override @override
...@@ -831,7 +1065,7 @@ class RadialGradient extends Gradient { ...@@ -831,7 +1065,7 @@ class RadialGradient extends Gradient {
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
if (identical(this, other)) if (identical(this, other))
return true; return true;
if (other is! RadialGradient) if (runtimeType != other.runtimeType)
return false; return false;
final RadialGradient typedOther = other; final RadialGradient typedOther = other;
if (center != typedOther.center || if (center != typedOther.center ||
......
...@@ -1811,6 +1811,41 @@ class RenderFractionalTranslation extends RenderProxyBox { ...@@ -1811,6 +1811,41 @@ class RenderFractionalTranslation extends RenderProxyBox {
/// ///
/// The [hitTest] method is called when the user interacts with the underlying /// The [hitTest] method is called when the user interacts with the underlying
/// render object, to determine if the user hit the object or missed it. /// render object, to determine if the user hit the object or missed it.
///
/// ## Sample code
///
/// This sample extends the same code shown for [RadialGradient] to create a
/// custom painter that paints a sky.
///
/// ```dart
/// class Sky extends CustomPainter {
/// @override
/// void paint(Canvas canvas, Size size) {
/// var rect = Offset.zero & size;
/// var gradient = new RadialGradient(
/// center: const FractionalOffset(0.7, 0.2),
/// radius: 0.2,
/// colors: [const Color(0xFFFFFF00), const Color(0xFF0099FF)],
/// stops: [0.4, 1.0],
/// );
/// canvas.drawRect(
/// rect,
/// new Paint()..shader = gradient.createShader(rect),
/// );
/// }
///
/// @override
/// bool shouldRepaint(CustomPainter oldDelegate) => false;
/// }
/// ```
///
/// See also:
///
/// * [Canvas], the class that a custom painter uses to paint.
/// * [CustomPaint], the widget that uses [CustomPainter], and whose sample
/// code shows how to use the above `Sky` class.
/// * [RadialGradient], whose sample code section shows a different take
/// on the sample code above.
abstract class CustomPainter extends Listenable { abstract class CustomPainter extends Listenable {
/// Creates a custom painter. /// Creates a custom painter.
/// ///
......
...@@ -198,10 +198,32 @@ class BackdropFilter extends SingleChildRenderObjectWidget { ...@@ -198,10 +198,32 @@ class BackdropFilter extends SingleChildRenderObjectWidget {
/// a child, they attempt to size themselves to the [size], which defaults to /// a child, they attempt to size themselves to the [size], which defaults to
/// [Size.zero]. /// [Size.zero].
/// ///
/// ## Sample code
///
/// This example shows how the sample custom painter shown at [CustomPainter]
/// could be used in a [CustomPaint] widget to display a background to some
/// text.
///
/// ```dart
/// new CustomPaint(
/// painter: new Sky(),
/// child: new Center(
/// child: new Text(
/// 'Once upon a time...',
/// style: const TextStyle(
/// fontSize: 40.0,
/// fontWeight: FontWeight.w900,
/// color: const Color(0xFFFFFFFF),
/// ),
/// ),
/// ),
/// ),
/// ```
///
/// See also: /// See also:
/// ///
/// * [CustomPainter]. /// * [CustomPainter], the class to extend when creating custom painters.
/// * [Canvas]. /// * [Canvas], the class that a custom painter uses to paint.
class CustomPaint extends SingleChildRenderObjectWidget { class CustomPaint extends SingleChildRenderObjectWidget {
/// Creates a widget that delegates its painting. /// Creates a widget that delegates its painting.
const CustomPaint({ Key key, this.painter, this.foregroundPainter, this.size: Size.zero, Widget child }) const CustomPaint({ Key key, this.painter, this.foregroundPainter, this.size: Size.zero, Widget child })
......
...@@ -17,9 +17,33 @@ import 'image.dart'; ...@@ -17,9 +17,33 @@ import 'image.dart';
/// ///
/// Commonly used with [BoxDecoration]. /// Commonly used with [BoxDecoration].
/// ///
/// ## Sample code
///
/// This sample shows a radial gradient that draws a moon on a night sky:
///
/// ```dart
/// new DecoratedBox(
/// decoration: new BoxDecoration(
/// gradient: new RadialGradient(
/// center: const FractionalOffset(0.25, 0.3),
/// radius: 0.15,
/// colors: <Color>[
/// const Color(0xFFEEEEEE),
/// const Color(0xFF111133),
/// ],
/// stops: <double>[0.9, 1.0],
/// ),
/// ),
/// ),
/// ```
///
/// See also: /// See also:
/// ///
/// * [DecoratedBoxTransition], the version of this class that animates on the [decoration] property. /// * [DecoratedBoxTransition], the version of this class that animates on the
/// [decoration] property.
/// * [Decoration], which you can extend to provide other effects with
/// [DecoratedBox].
/// * [CustomPaint], another way to draw custom effects from the widget layer.
class DecoratedBox extends SingleChildRenderObjectWidget { class DecoratedBox extends SingleChildRenderObjectWidget {
/// Creates a widget that paints a [Decoration]. /// Creates a widget that paints a [Decoration].
/// ///
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment