Surface class

📦 Surface

An AnimatedContainer Widget and Material with a number of parameters for both appearance and behavior; some of which are just convenience shortcuts, such as providesFeedback, that modify very little code.

Property borderAlignment has hard-coded recognition of all nine Alignment geometries and will determine which side(s) receive a special border treatment according to property borderRatio; defaults at borderRatio: 2 which makes the borderAlignment sides twice as thick, but these borders made be made thinner than the others by passing 0 > borderRatio > 1.

Considering:

  1. SurfaceCorners property corners;
  2. properties tappable, onTap, providesFeedback & inkHighlightColor, inkSplashColor;
  3. SurfaceFilter passed as filterStyle and related doubles filterSurfaceBlur, filterMaterialBlur & filterChildBlur;
  4. and the duration property for intrinsic property-change animations;

A Surface is robustly customizable and, watch out, could also be expensive.


  • WARNING Only pass filterStyle parameter for which you intend on passing each relevant filterBlur parameter.
    • Not only are the blurry BackdropFilters expensive, but the inheritance/ancestory behavior is strange.
    • If all three filters are active via SurfaceFilter.MULTILAYER, passing filterBorderBlur: 0 eliminates the remaining children filters, regardless of their passed blur value.
    • This behavior can be worked-around by setting any parent filter value (BORDER > MATERIAL > CHILD) to just above 0, specifically > (_MINIMUM_BLUR== 0.0003), but in this case a different filterStyle value should be used anyway that only employs the one or two appropriate filter(s).


Simple Examples:

// white [Surface] with a black border that's thicker on bottom & right, with rounded corners
Surface(borderAlignment: Alignment.bottomRight, borderRadius: 10)
// red [Surface] with symmetrical thick, black border and square corners (borderRadius is ignored)
Surface(borderThickness: 6, corners: SurfaceCorners.SQUARE, color: Colors.red, borderRadius: 5)
// white [Surface] with a gradient border that's thicker on top and left, with two beveled corners
Surface(borderAlignment: Alignment.topLeft, corners: SurfaceCorners.BEVEL, flipBevels: true, borderGradient: LinearGradient(...))
Inheritance

Constructors

Surface({double width, double height, Color color = _DEFAULT_COLOR, bool disableBorder = false, bool tappable = true, SurfaceCorners corners = SurfaceCorners.ROUND, double radius, double borderThickness = 3.0, Color borderColor = _DEFAULT_COLOR_BORDER, AlignmentGeometry borderAlignment, double borderRatio = 2.0, Gradient gradient, Gradient borderGradient, Color inkSplashColor, Color inkHighlightColor, SurfaceFilter filterStyle = SurfaceFilter.NONE, Duration duration = _DEFAULT_DURATION, Curve curve = Curves.easeIn, bool providesFeedback = false, EdgeInsets margin = const EdgeInsets.all(0), EdgeInsets padding = const EdgeInsets.all(0), SurfacePadding paddingStyle = SurfacePadding.PAD_CHILD, bool flipBevels = false, double filterSurfaceBlur = _DEFAULT_BLUR, double filterMaterialBlur = _DEFAULT_BLUR, double filterChildBlur = _DEFAULT_BLUR, VoidCallback onTap, Widget child})
const

Properties

borderAlignment AlignmentGeometry
Using an Alignment, determine a side or sides to receive a special treatment.
final
borderColor Color
If passed gradient or borderGradient, the Color parameters are ignored.
final
borderGradient Gradient
If gradients are passed, then Color parameters are ignored.
final
borderRatio double
borderThickness is applied as padding to innerContainer insetting the innerSurface. [...]
final
borderThickness double
borderThickness is applied as padding to innerContainer insetting the innerSurface. [...]
final
child Widget
The Widget to render inside considering all layout parameters.
final
color Color
If passed gradient or borderGradient, the Color parameters are ignored.
final
corners SurfaceCorners
See SurfaceCorners for a small list of availabe Surface shapes. Default is SurfaceCorners.ROUND, but SurfaceCorners.BEVEL is fun.
final
curve Curve
The animation Curve to employ when this Surface is intrinsically animated.
final
disableBorder bool
The borderContainer will not be rendered if true. [...]
final
duration Duration
The Duration that the internal AnimatedContainers use for intrinsic property-change animations.
final
filterChildBlur double
filterBlur parameters default to _MINIMUM_BLUR == 0.0000001 so that upper-layered filters are not erased by an ancestor filter having 0 radius. [...]
final
filterMaterialBlur double
filterBlur parameters default to _MINIMUM_BLUR == 0.0000001 so that upper-layered filters are not erased by an ancestor filter having 0 radius. [...]
final
filterStyle SurfaceFilter
See SurfaceFilter for a breakdown on the layering of up to three blur filters. Radii of blur filters handled independently by filterSurfaceBlur, filterMaterialBlur, and filterChildBlur, supplied in asending z-axis order.
final
filterSurfaceBlur double
filterBlur parameters default to _MINIMUM_BLUR == 0.0000001 so that upper-layered filters are not erased by an ancestor filter having 0 radius. [...]
final
flipBevels bool
Only if corners == SurfaceCorners.BEVEL will this parameter then flip the two beveled corners horizontally across x-axis. [...]
final
gradient Gradient
If gradients are passed, then Color parameters are ignored.
final
hashCode int
The hash code for this object. [...]
@nonVirtual, read-only, inherited
height double
The width and height follow rules of AnimatedContainer, but apply to either the Surface.borderContainer or, if disableBorers: true, the Surface.innerSurface directly. [...]
final
inkHighlightColor Color
If tappable == true the InkResponse appearance may be customized. Otherwise no InkResponse is rendered with the Surface.
final
inkSplashColor Color
If tappable == true the InkResponse appearance may be customized. Otherwise no InkResponse is rendered with the Surface.
final
key Key
Controls how one widget replaces another widget in the tree. [...]
final, inherited
margin EdgeInsets
If disableBorder == true the Surface margin is properly handled by innerSurface; but otherwise margin applies to borderContainer and the Surface as a whole, ignored by innerSurface. [...]
final
onTap VoidCallback
Disabled by tappable == false. Pass a function to peform any time the InkResponse on this Surface responds to a tap input.
final
padding EdgeInsets
If disableBorder == true the Surface margin is properly handled by innerSurface; but otherwise margin applies to borderContainer and the Surface as a whole, ignored by innerSurface. [...]
final
paddingStyle SurfacePadding
The padding value may be (default) passed entirely to the child, but optionally may be given to a _clipper within innerSurface before rendering child, or split evenly between the two. [...]
final
providesFeedback bool
Not only does tappable mean the Surface will provide onTap, it also adds an InkResponse to the Material before rendering child. [...]
final
radius double
The width and height follow rules of AnimatedContainer, but apply to either the Surface.borderContainer or, if disableBorers: true, the Surface.innerSurface directly. [...]
final
runtimeType Type
A representation of the runtime type of the object.
read-only, inherited
tappable bool
Not only does tappable mean the Surface will provide onTap, it also adds an InkResponse to the Material before rendering child. [...]
final
width double
The width and height follow rules of AnimatedContainer, but apply to either the Surface.borderContainer or, if disableBorers: true, the Surface.innerSurface directly. [...]
final

Methods

build(BuildContext context) Widget
👷‍♂️ Build Surface
override
createElement() StatelessElement
Creates a StatelessElement to manage this widget's location in the tree. [...]
inherited
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children. [...]
@protected, inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node. [...]
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a non-existent method or property is accessed. [...]
inherited
toDiagnosticsNode({String name, DiagnosticsTreeStyle style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep. [...]
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) String
Returns a string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a string representation of this node and its descendants. [...]
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object. [...]
inherited
toStringShort() String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) bool
The equality operator. [...]
@nonVirtual, inherited