Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 158 additions & 0 deletions examples/api/lib/widgets/sliver/decorated_sliver.1.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// 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/material.dart';

/// Flutter code example for [DecoratedSliver]
/// with clipping turned off in a parent [CustomScrollView].

void main() => runApp(const DecoratedSliverClipExampleApp());

class DecoratedSliverClipExampleApp extends StatelessWidget {
const DecoratedSliverClipExampleApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'DecoratedSliver Clip Example',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const DecoratedSliverClipExample(),
);
}
}

class DecoratedSliverClipExample extends StatefulWidget {
const DecoratedSliverClipExample({super.key});

@override
State<DecoratedSliverClipExample> createState() => _DecoratedSliverClipExampleState();
}

class _DecoratedSliverClipExampleState extends State<DecoratedSliverClipExample> {
double _height = 225.0;
bool _isClipped = false;

@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFF1C1C1C),
body: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Switch(
inactiveTrackColor: Colors.cyan,
activeColor: Colors.pink,
onChanged: (bool value) {
setState(() {
_isClipped = value;
});
},
value: _isClipped,
),
Slider(
activeColor: Colors.pink,
inactiveColor: Colors.cyan,
onChanged: (double value) {
setState(() {
_height = value;
});
},
value: _height,
min: 150,
max: 225,
),
],
),
const SizedBox(
height: 20.0,
),
Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(24.0),
child: SizedBox(
width: 400,
height: _height,
child: ResizableCustomScrollView(isClipped: _isClipped),
),
),
Positioned(
top: _height,
left: 0,
right: 0,
child: SizedBox(
height: MediaQuery.of(context).size.height - _height,
width: double.infinity,
),
),
],
),
],
),
);
}
}

class ResizableCustomScrollView extends StatelessWidget {
const ResizableCustomScrollView({
super.key,
required this.isClipped,
});

final bool isClipped;

@override
Widget build(BuildContext context) {
return CustomScrollView(
// The clip behavior defaults to Clip.hardEdge if no argument is provided.
clipBehavior: isClipped ? Clip.hardEdge : Clip.none,
slivers: <Widget>[
DecoratedSliver(
decoration: const ShapeDecoration(
color: Color(0xFF2C2C2C),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(6),
),
),
shadows: <BoxShadow>[
BoxShadow(
color: Colors.cyan,
offset: Offset(3, 3),
blurRadius: 24,
),
],
),
sliver: SliverList.builder(
itemCount: 5,
itemBuilder: (_, int index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
const Icon(
Icons.add_box,
color: Color(0xFFA8A8A8),
),
Flexible(
child: Text(
'Item $index',
style: const TextStyle(
color: Color(0xFFA8A8A8),
),
),
),
],
),
),
),
),
],
);
}
}
42 changes: 42 additions & 0 deletions examples/api/test/widgets/sliver/decorated_sliver.1_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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/material.dart';
import 'package:flutter_api_samples/widgets/sliver/decorated_sliver.1.dart' as example;
import 'package:flutter_test/flutter_test.dart';

void main() {
testWidgets('CustomScrollView clipBehavior is Clip.none when is Clipped is false', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: example.DecoratedSliverClipExample(),
),
);

final CustomScrollView customScrollView = tester.widget(find.byType(CustomScrollView));

expect(customScrollView.clipBehavior, equals(Clip.none));
});

testWidgets('Verify the DecoratedSliver has shadow property in decoration', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: example.ResizableCustomScrollView(isClipped: false),
),
);

final DecoratedSliver decoratedSliver = tester.widget(find.byType(DecoratedSliver));
final ShapeDecoration shapeDecoration = decoratedSliver.decoration as ShapeDecoration;

expect(shapeDecoration.shadows, isNotEmpty);
});

testWidgets('Verify Slider and Switch widgets', (WidgetTester tester) async {
await tester.pumpWidget(const example.DecoratedSliverClipExampleApp());

expect(find.byType(Slider), findsOneWidget);

expect(find.byType(Switch), findsOneWidget);
});
}
16 changes: 14 additions & 2 deletions packages/flutter/lib/src/widgets/decorated_sliver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,27 @@ import 'image.dart';
///
/// 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 dartpad}
/// This sample shows a radial gradient that draws a moon on a night sky:
///
/// ** See code in examples/api/lib/widgets/sliver/decorated_sliver.0.dart **
/// {@end-tool}
///
/// {@tool dartpad}
/// This example demonstrates how the [CustomScrollView.clipBehavior]
/// impacts a decorated sliver's appearance.
///
/// The [Switch] determines whether clipping is enabled, and
/// the [Slider] adjusts the height of window.
///
/// ** See code in examples/api/lib/widgets/sliver/decorated_sliver.1.dart **
/// {@end-tool}
///
/// This widget does not apply any additional clipping to its [child].
/// To clip a child based on the [Decoration]'s shape, consider using
/// a [ClipPath] widget.
///
/// See also:
///
/// * [DecoratedBox], the version of this class that works with RenderBox widgets.
Expand Down