From a02cd540f6f990f3f7857f25f66b86cdb1f20c5d Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 13 Jul 2022 10:38:07 -0700 Subject: [PATCH] Revert "[framework] SliverDecoration" (#107561) --- .../lib/src/painting/box_decoration.dart | 2 - .../flutter/lib/src/widgets/container.dart | 1 - .../lib/src/widgets/sliver_decoration.dart | 208 ---------------- packages/flutter/lib/widgets.dart | 1 - .../test/widgets/sliver_decoration_test.dart | 230 ------------------ 5 files changed, 442 deletions(-) delete mode 100644 packages/flutter/lib/src/widgets/sliver_decoration.dart delete mode 100644 packages/flutter/test/widgets/sliver_decoration_test.dart diff --git a/packages/flutter/lib/src/painting/box_decoration.dart b/packages/flutter/lib/src/painting/box_decoration.dart index 70ab5f7b68..01164b4454 100644 --- a/packages/flutter/lib/src/painting/box_decoration.dart +++ b/packages/flutter/lib/src/painting/box_decoration.dart @@ -68,8 +68,6 @@ import 'image_provider.dart'; /// /// * [DecoratedBox] and [Container], widgets that can be configured with /// [BoxDecoration] objects. -/// * [SliverDecoration],a widget that can be configured with [BoxDecoration] -/// objects that is specialized for rendering with slivers. /// * [CustomPaint], a widget that lets you draw arbitrary graphics. /// * [Decoration], the base class which lets you define other decorations. class BoxDecoration extends Decoration { diff --git a/packages/flutter/lib/src/widgets/container.dart b/packages/flutter/lib/src/widgets/container.dart index 53e614cec8..f157fa5ce9 100644 --- a/packages/flutter/lib/src/widgets/container.dart +++ b/packages/flutter/lib/src/widgets/container.dart @@ -52,7 +52,6 @@ import 'image.dart'; /// * [Decoration], which you can extend to provide other effects with /// [DecoratedBox]. /// * [CustomPaint], another way to draw custom effects from the widget layer. -/// * [SliverDecoration], which paints a [Decoration] around a sliver. class DecoratedBox extends SingleChildRenderObjectWidget { /// Creates a widget that paints a [Decoration]. /// diff --git a/packages/flutter/lib/src/widgets/sliver_decoration.dart b/packages/flutter/lib/src/widgets/sliver_decoration.dart deleted file mode 100644 index 41bc6feb75..0000000000 --- a/packages/flutter/lib/src/widgets/sliver_decoration.dart +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/rendering.dart'; - -import 'basic.dart'; -import 'framework.dart'; -import 'image.dart'; - -/// A sliver widget that paints a [Decoration] either before or after its child -/// paints. -/// -/// Unlike [DecoratedBox], this widget expects its child to be a sliver, and -/// must be placed in a widget that expects a sliver. This can allow decorating the -/// background of a [SliverList] without resorting to a shrink-wrapped list view or -/// column layout. -/// -/// Commonly used with [BoxDecoration]. -/// -/// The [child] is not clipped. To clip a child to the shape of a particular -/// [ShapeDecoration], consider using a [ClipPath] widget. -/// -/// {@tool snippet} -/// -/// This sample shows a radial gradient that draws a moon on a night sky: -/// -/// ```dart -/// SliverDecoration( -/// decoration: const BoxDecoration( -/// gradient: RadialGradient( -/// center: Alignment(-0.5, -0.6), -/// radius: 0.15, -/// colors: [ -/// Color(0xFFEEEEEE), -/// Color(0xFF111133), -/// ], -/// stops: [0.9, 1.0], -/// ), -/// ), -/// sliver: SliverList( -/// delegate: SliverChildListDelegate([ -/// const Text('Goodnight Moon'), -/// ]), -/// ), -/// ) -/// ``` -/// {@end-tool} -/// -/// See also: -/// -/// * [DecoratedBox], the version of this class that works with regular widgets. -/// * [Decoration], which you can extend to provide other effects with -/// [SliverDecoration]. -/// * [CustomPaint], another way to draw custom effects from the widget layer. -class SliverDecoration extends SingleChildRenderObjectWidget { - /// Creates a widget that paints a [Decoration]. - /// - /// The [decoration] and [position] arguments must not be null. By default the - /// decoration paints behind the child. - const SliverDecoration({ - super.key, - required this.decoration, - this.position = DecorationPosition.background, - Widget? sliver, - }) : super(child: sliver); - - /// What decoration to paint. - /// - /// Commonly a [BoxDecoration]. - final Decoration decoration; - - /// Whether to paint the box decoration behind or in front of the child. - final DecorationPosition position; - - @override - RenderSliverDecoration createRenderObject(BuildContext context) { - return RenderSliverDecoration( - decoration: decoration, - position: position, - configuration: createLocalImageConfiguration(context), - ); - } - - @override - void updateRenderObject(BuildContext context, RenderSliverDecoration renderObject) { - renderObject - ..decoration = decoration - ..position = position - ..configuration = createLocalImageConfiguration(context); - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - final String label; - switch (position) { - case DecorationPosition.background: - label = 'bg'; - break; - case DecorationPosition.foreground: - label = 'fg'; - break; - } - properties.add(EnumProperty('position', position, level: DiagnosticLevel.hidden)); - properties.add(DiagnosticsProperty(label, decoration)); - } -} - -/// Paints a [Decoration] either before or after its child paints. -class RenderSliverDecoration extends RenderProxySliver { - /// Creates a decorated sliver. - /// - /// The [decoration], [position], and [configuration] arguments must not be - /// null. By default the decoration paints behind the child. - /// - /// The [ImageConfiguration] will be passed to the decoration (with the size - /// filled in) to let it resolve images. - RenderSliverDecoration({ - required Decoration decoration, - DecorationPosition position = DecorationPosition.background, - ImageConfiguration configuration = ImageConfiguration.empty, - }) : _decoration = decoration, - _position = position, - _configuration = configuration; - - /// What decoration to paint. - /// - /// Commonly a [BoxDecoration]. - Decoration get decoration => _decoration; - Decoration _decoration; - set decoration(Decoration value) { - if (value == decoration) { - return; - } - _decoration = value; - _painter?.dispose(); - _painter = decoration.createBoxPainter(markNeedsPaint); - markNeedsPaint(); - } - - /// Whether to paint the box decoration behind or in front of the child. - DecorationPosition get position => _position; - DecorationPosition _position; - set position(DecorationPosition value) { - if (value == position) { - return; - } - _position = value; - markNeedsPaint(); - } - - /// The settings to pass to the decoration when painting, so that it can - /// resolve images appropriately. See [ImageProvider.resolve] and - /// [BoxPainter.paint]. - /// - /// The [ImageConfiguration.textDirection] field is also used by - /// direction-sensitive [Decoration]s for painting and hit-testing. - ImageConfiguration get configuration => _configuration; - ImageConfiguration _configuration; - set configuration(ImageConfiguration value) { - if (value == configuration) { - return; - } - _configuration = value; - markNeedsPaint(); - } - - BoxPainter? _painter; - - @override - void attach(covariant PipelineOwner owner) { - _painter = decoration.createBoxPainter(markNeedsPaint); - super.attach(owner); - } - - @override - void detach() { - _painter?.dispose(); - _painter = null; - super.detach(); - } - - @override - void dispose() { - _painter?.dispose(); - _painter = null; - super.dispose(); - } - - @override - void paint(PaintingContext context, Offset offset) { - if (child != null && child!.geometry!.visible) { - final SliverPhysicalParentData childParentData = child!.parentData! as SliverPhysicalParentData; - final Size childSize = Size(constraints.crossAxisExtent, child!.geometry!.paintExtent); - final Offset childOffset = offset + childParentData.paintOffset; - - if (position == DecorationPosition.background) { - _painter!.paint(context.canvas, childOffset, configuration.copyWith(size: childSize)); - } - context.paintChild(child!, offset + childParentData.paintOffset); - - if (position == DecorationPosition.foreground) { - _painter!.paint(context.canvas, childOffset, configuration.copyWith(size: childSize)); - } - } - } -} diff --git a/packages/flutter/lib/widgets.dart b/packages/flutter/lib/widgets.dart index f44022a11c..fecda72215 100644 --- a/packages/flutter/lib/widgets.dart +++ b/packages/flutter/lib/widgets.dart @@ -119,7 +119,6 @@ export 'src/widgets/shortcuts.dart'; export 'src/widgets/single_child_scroll_view.dart'; export 'src/widgets/size_changed_layout_notifier.dart'; export 'src/widgets/sliver.dart'; -export 'src/widgets/sliver_decoration.dart'; export 'src/widgets/sliver_fill.dart'; export 'src/widgets/sliver_layout_builder.dart'; export 'src/widgets/sliver_persistent_header.dart'; diff --git a/packages/flutter/test/widgets/sliver_decoration_test.dart b/packages/flutter/test/widgets/sliver_decoration_test.dart deleted file mode 100644 index 4549e333eb..0000000000 --- a/packages/flutter/test/widgets/sliver_decoration_test.dart +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file is run as part of a reduced test set in CI on Mac and Windows -// machines. -@Tags(['reduced-test-set']) -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - testWidgets('SliverDecoration creates, paints, and disposes BoxPainter', (WidgetTester tester) async { - final TestDecoration decoration = TestDecoration(); - await tester.pumpWidget(MaterialApp( - home: Scaffold( - body: CustomScrollView( - slivers: [ - SliverDecoration( - decoration: decoration, - sliver: const SliverToBoxAdapter( - child: SizedBox(width: 100, height: 100), - ), - ) - ], - ) - ) - )); - - expect(decoration.painters, hasLength(1)); - expect(decoration.painters.last.lastConfiguration!.size, const Size(800, 100)); - expect(decoration.painters.last.lastOffset, Offset.zero); - expect(decoration.painters.last.disposed, false); - - await tester.pumpWidget(const SizedBox()); - - expect(decoration.painters, hasLength(1)); - expect(decoration.painters.last.disposed, true); - }); - - testWidgets('SliverDecoration can update box painter', (WidgetTester tester) async { - final TestDecoration decorationA = TestDecoration(); - final TestDecoration decorationB = TestDecoration(); - - Decoration activateDecoration = decorationA; - late void Function(void Function()) localSetState; - await tester.pumpWidget(MaterialApp( - home: Scaffold( - body: StatefulBuilder( - builder:(BuildContext context, void Function(void Function()) setState) { - localSetState = setState; - return CustomScrollView( - slivers: [ - SliverDecoration( - decoration: activateDecoration, - sliver: const SliverToBoxAdapter( - child: SizedBox(width: 100, height: 100), - ), - ) - ], - ); - }, - ) - ) - )); - - expect(decorationA.painters, hasLength(1)); - expect(decorationA.painters.last.paintCount, 1); - expect(decorationB.painters, hasLength(0)); - - localSetState(() { - activateDecoration = decorationB; - }); - await tester.pump(); - - expect(decorationA.painters, hasLength(1)); - expect(decorationB.painters, hasLength(1)); - expect(decorationB.painters.last.paintCount, 1); - }); - - testWidgets('SliverDecoration can update DecorationPosition', (WidgetTester tester) async { - final TestDecoration decoration = TestDecoration(); - - DecorationPosition activePosition = DecorationPosition.foreground; - late void Function(void Function()) localSetState; - await tester.pumpWidget(MaterialApp( - home: Scaffold( - body: StatefulBuilder( - builder:(BuildContext context, void Function(void Function()) setState) { - localSetState = setState; - return CustomScrollView( - slivers: [ - SliverDecoration( - decoration: decoration, - position: activePosition, - sliver: const SliverToBoxAdapter( - child: SizedBox(width: 100, height: 100), - ), - ) - ], - ); - }, - ) - ) - )); - - expect(decoration.painters, hasLength(1)); - expect(decoration.painters.last.paintCount, 1); - - localSetState(() { - activePosition = DecorationPosition.background; - }); - await tester.pump(); - - expect(decoration.painters, hasLength(1)); - expect(decoration.painters.last.paintCount, 2); - }); - - testWidgets('SliverDecoration golden test', (WidgetTester tester) async { - const BoxDecoration decoration = BoxDecoration( - color: Colors.blue, - ); - - final Key backgroundKey = UniqueKey(); - await tester.pumpWidget(MaterialApp( - home: Scaffold( - body: RepaintBoundary( - key: backgroundKey, - child: CustomScrollView( - slivers: [ - SliverDecoration( - decoration: decoration, - sliver: SliverPadding( - padding: const EdgeInsets.all(16), - sliver: SliverList( - delegate: SliverChildListDelegate.fixed([ - Container( - height: 100, - color: Colors.red, - ), - Container( - height: 100, - color: Colors.yellow, - ), - Container( - height: 100, - color: Colors.red, - ), - ]), - ), - ), - ), - ], - ), - ), - ) - )); - - await expectLater(find.byKey(backgroundKey), matchesGoldenFile('decorated_sliver.moon.background.png')); - - final Key foregroundKey = UniqueKey(); - await tester.pumpWidget(MaterialApp( - home: Scaffold( - body: RepaintBoundary( - key: foregroundKey, - child: CustomScrollView( - slivers: [ - SliverDecoration( - decoration: decoration, - position: DecorationPosition.foreground, - sliver: SliverPadding( - padding: const EdgeInsets.all(16), - sliver: SliverList( - delegate: SliverChildListDelegate.fixed([ - Container( - height: 100, - color: Colors.red, - ), - Container( - height: 100, - color: Colors.yellow, - ), - Container( - height: 100, - color: Colors.red, - ), - ]), - ), - ), - ), - ], - ), - ), - ) - )); - - await expectLater(find.byKey(foregroundKey), matchesGoldenFile('decorated_sliver.moon.foreground.png')); - }); -} - -class TestDecoration extends Decoration { - final List painters = []; - - @override - BoxPainter createBoxPainter([VoidCallback? onChanged]) { - final TestBoxPainter painter = TestBoxPainter(); - painters.add(painter); - return painter; - } -} - -class TestBoxPainter extends BoxPainter { - Offset? lastOffset; - ImageConfiguration? lastConfiguration; - bool disposed = false; - int paintCount = 0; - - @override - void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { - lastOffset = offset; - lastConfiguration = configuration; - paintCount += 1; - } - - @override - void dispose() { - assert(!disposed); - disposed = true; - super.dispose(); - } -}