You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This proposal introduces new widgets, SliverClipRect and SliverClipRRect. Those widgets serve as the Sliver equivalent of the existing ClipRect and ClipRRect widgets. It clips its child sliver using a rectangle / rounded rectangle and include specific logic to handle SliverConstraints.overlap, allowing for the visual removal of content that scrolls underneath pinned headers.
2. Background & Motivation
The Problem
Currently, the ClipRect and ClipRRect widgets only support RenderBox protocol.
There are two primary scenarios where clipping is essential in the Sliver world, but currently difficult to achieve:
Visual Styling: Applying a hard clip to a group of slivers (e.g., inside a SliverMainAxisGroup or SliverDecoratedBox).
Overlap Management: When using pinned headers (like SliverAppBar or SliverPersistentHeader) with transparent or semi-transparent backgrounds. By default, scrolling content paints underneath the pinned header. If the header is transparent, the scrolling content is visible, which is often undesirable. Developers need a way to "clip" the scrolling content exactly at the point where it overlaps with the pinned header.
The Solution
SliverClipRect/SliverClipRRect solve this by creating a RenderSliverClipRect/RenderSliverClipRRect. Those render object:
Accept CustomClipper<Rect> and CustomClipper<RRect>.
Optionally accounts for constraints.overlap to automatically clip the portion of the child obstructed by pinned headers.
Correctly handles hit-testing, ensuring that clipped/overlapped areas do not consume touch events.
3. Design
API Surface
The API mirrors the existing ClipRect and ClipRRect but adds the clipOverlap property specific to the Sliver protocol.
classSliverClipRectextendsSingleChildRenderObjectWidget {
constSliverClipRect({
super.key,
super.child,
this.clipper,
this.clipBehavior =Clip.hardEdge,
this.clipOverlap =true,
});
/// If non-null, determines which clip rectangle to use.finalCustomClipper<Rect>? clipper;
/// {@macro flutter.rendering.ClipRectLayer.clipBehavior}finalClip clipBehavior;
/// Whether to automatically clip the portion of the child that is overlapped /// by preceding pinned slivers. /// /// If true, the clip rect will be adjusted to exclude the area defined by /// [SliverConstraints.overlap].finalbool clipOverlap;
}
classSliverClipRRectextendsSingleChildRenderObjectWidget {
/// Creates a sliver that clips its child using a rounded rectangle.constSliverClipRRect({
super.key,
requiredWidget sliver,
this.borderRadius =BorderRadius.zero,
this.clipper,
this.clipBehavior =Clip.antiAlias,
this.clipOverlap =true,
}) :super(child: sliver);
/// The border radius of the rounded corners. /// /// Values are clamped so that horizontal and vertical radii sums do not /// exceed width/height. /// /// This value is ignored if [clipper] is non-null.finalBorderRadiusGeometry borderRadius;
/// If non-null, determines which clip to use.finalCustomClipper<RRect>? clipper;
/// {@macro flutter.rendering.ClipRectLayer.clipBehavior}finalClip clipBehavior;
/// Whether to automatically clip the portion of the child that is overlapped /// by preceding pinned slivers. /// /// If true, the clip rect will be adjusted to exclude the area defined by /// [SliverConstraints.overlap].finalbool clipOverlap;
}
Rendering Logic
The RenderSliverClipRect/RenderSliverClipRRect calculate the clip rect/rrect based on the child's paint bounds. If clipOverlap is true, it intersects the calculated clip rect with the visible portion of the viewport (excluding the overlap defined in constraints).
4. Use Cases
Use Case 1: Grouped Decoration with Hard Edges
This scenario involves a group of slivers wrapped in a decoration (e.g., a gradient). We want to ensure that if the decoration has specific bounds, the children are clipped strictly to those bounds, ignoring overlap logic.
Use Case 2: Transparent Pinned Header
This scenario involves a design where the SliverAppBar (or pinned header) has no background (transparent), but the Scaffold has a complex background (e.g., a gradient).
Without clipping, as items scroll up, they would become visible behind the text of the SliverAppBar because the App Bar is transparent. Using SliverClipRect with clipOverlap: true (the default) ensures items disappear the moment they hit the overlap point.
Example
The example below combines the two previous use cases and works with PR #179003.
1. Overview
This proposal introduces new widgets,
SliverClipRectandSliverClipRRect. Those widgets serve as the Sliver equivalent of the existingClipRectandClipRRectwidgets. It clips its child sliver using a rectangle / rounded rectangle and include specific logic to handleSliverConstraints.overlap, allowing for the visual removal of content that scrolls underneath pinned headers.2. Background & Motivation
The Problem
Currently, the
ClipRectandClipRRectwidgets only supportRenderBoxprotocol.There are two primary scenarios where clipping is essential in the Sliver world, but currently difficult to achieve:
SliverMainAxisGrouporSliverDecoratedBox).SliverAppBarorSliverPersistentHeader) with transparent or semi-transparent backgrounds. By default, scrolling content paints underneath the pinned header. If the header is transparent, the scrolling content is visible, which is often undesirable. Developers need a way to "clip" the scrolling content exactly at the point where it overlaps with the pinned header.The Solution
SliverClipRect/SliverClipRRectsolve this by creating aRenderSliverClipRect/RenderSliverClipRRect. Those render object:CustomClipper<Rect>andCustomClipper<RRect>.constraints.overlapto automatically clip the portion of the child obstructed by pinned headers.3. Design
API Surface
The API mirrors the existing
ClipRectandClipRRectbut adds theclipOverlapproperty specific to the Sliver protocol.Rendering Logic
The
RenderSliverClipRect/RenderSliverClipRRectcalculate the clip rect/rrect based on the child's paint bounds. IfclipOverlapis true, it intersects the calculated clip rect with the visible portion of the viewport (excluding the overlap defined in constraints).4. Use Cases
Use Case 1: Grouped Decoration with Hard Edges
This scenario involves a group of slivers wrapped in a decoration (e.g., a gradient). We want to ensure that if the decoration has specific bounds, the children are clipped strictly to those bounds, ignoring overlap logic.
Use Case 2: Transparent Pinned Header
This scenario involves a design where the
SliverAppBar(or pinned header) has no background (transparent), but theScaffoldhas a complex background (e.g., a gradient).Without clipping, as items scroll up, they would become visible behind the text of the
SliverAppBarbecause the App Bar is transparent. UsingSliverClipRectwithclipOverlap: true(the default) ensures items disappear the moment they hit the overlap point.Example
The example below combines the two previous use cases and works with PR #179003.
demo.webm
Optional proposal
In a new PR, we eventually can add :
SliverClipOval,SliverClipPathandSliverRSuperellipse.