forked from flutter/flutter
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
…lutter#145536) fixes [Introduce animation customizable with `AnimationStyle` to `BottomSheet`](flutter#145532) ### Default bottom sheet animation ![00-ezgif com-video-to-gif-converter](https://github.com/flutter/flutter/assets/48603081/a295b002-b310-4dea-8bc4-23b1d299748c) ### Custom bottom sheet animation ![01-ezgif com-video-to-gif-converter](https://github.com/flutter/flutter/assets/48603081/8c5c3d5f-e67d-4ed5-880d-f17d262087e1) ### No bottom sheet animation ![02-ezgif com-video-to-gif-converter](https://github.com/flutter/flutter/assets/48603081/872409d8-8a8d-4db9-b95b-7f96a62cdffc)
- Loading branch information
1 parent
62adaff
commit 23687c5
Showing
12 changed files
with
1,007 additions
and
6 deletions.
There are no files selected for viewing
101 changes: 101 additions & 0 deletions
101
examples/api/lib/material/bottom_sheet/show_bottom_sheet.0.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// 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 sample for [showBottomSheet]. | ||
void main() => runApp(const BottomSheetExampleApp()); | ||
|
||
class BottomSheetExampleApp extends StatelessWidget { | ||
const BottomSheetExampleApp({super.key}); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return MaterialApp( | ||
home: Scaffold( | ||
appBar: AppBar(title: const Text('Bottom Sheet Sample')), | ||
body: const BottomSheetExample(), | ||
), | ||
); | ||
} | ||
} | ||
|
||
enum AnimationStyles { defaultStyle, custom, none } | ||
const List<(AnimationStyles, String)> animationStyleSegments = <(AnimationStyles, String)>[ | ||
(AnimationStyles.defaultStyle, 'Default'), | ||
(AnimationStyles.custom, 'Custom'), | ||
(AnimationStyles.none, 'None'), | ||
]; | ||
|
||
class BottomSheetExample extends StatefulWidget { | ||
const BottomSheetExample({super.key}); | ||
|
||
@override | ||
State<BottomSheetExample> createState() => _BottomSheetExampleState(); | ||
} | ||
|
||
class _BottomSheetExampleState extends State<BottomSheetExample> { | ||
Set<AnimationStyles> _animationStyleSelection = <AnimationStyles>{AnimationStyles.defaultStyle}; | ||
AnimationStyle? _animationStyle; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Center( | ||
child: Column( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
children: <Widget>[ | ||
SegmentedButton<AnimationStyles>( | ||
selected: _animationStyleSelection, | ||
onSelectionChanged: (Set<AnimationStyles> styles) { | ||
setState(() { | ||
_animationStyle = switch (styles.first) { | ||
AnimationStyles.defaultStyle => null, | ||
AnimationStyles.custom => AnimationStyle( | ||
duration: const Duration(seconds: 3), | ||
reverseDuration: const Duration(seconds: 1), | ||
), | ||
AnimationStyles.none => AnimationStyle.noAnimation, | ||
}; | ||
_animationStyleSelection = styles; | ||
}); | ||
}, | ||
segments: animationStyleSegments | ||
.map<ButtonSegment<AnimationStyles>>(((AnimationStyles, String) shirt) { | ||
return ButtonSegment<AnimationStyles>(value: shirt.$1, label: Text(shirt.$2)); | ||
}) | ||
.toList(), | ||
), | ||
const SizedBox(height: 10), | ||
ElevatedButton( | ||
child: const Text('showBottomSheet'), | ||
onPressed: () { | ||
showBottomSheet( | ||
context: context, | ||
sheetAnimationStyle: _animationStyle, | ||
builder: (BuildContext context) { | ||
return SizedBox.expand( | ||
child: Center( | ||
child: Column( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
mainAxisSize: MainAxisSize.min, | ||
children: <Widget>[ | ||
const Text('Bottom sheet'), | ||
ElevatedButton( | ||
child: const Text('Close'), | ||
onPressed: () => Navigator.pop(context), | ||
), | ||
], | ||
), | ||
), | ||
); | ||
}, | ||
); | ||
}, | ||
), | ||
], | ||
), | ||
); | ||
} | ||
} |
101 changes: 101 additions & 0 deletions
101
examples/api/lib/material/bottom_sheet/show_modal_bottom_sheet.2.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// 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 sample for [showModalBottomSheet]. | ||
void main() => runApp(const ModalBottomSheetApp()); | ||
|
||
class ModalBottomSheetApp extends StatelessWidget { | ||
const ModalBottomSheetApp({super.key}); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return MaterialApp( | ||
home: Scaffold( | ||
appBar: AppBar(title: const Text('Modal Bottom Sheet Sample')), | ||
body: const ModalBottomSheetExample(), | ||
), | ||
); | ||
} | ||
} | ||
|
||
enum AnimationStyles { defaultStyle, custom, none } | ||
const List<(AnimationStyles, String)> animationStyleSegments = <(AnimationStyles, String)>[ | ||
(AnimationStyles.defaultStyle, 'Default'), | ||
(AnimationStyles.custom, 'Custom'), | ||
(AnimationStyles.none, 'None'), | ||
]; | ||
|
||
class ModalBottomSheetExample extends StatefulWidget { | ||
const ModalBottomSheetExample({super.key}); | ||
|
||
@override | ||
State<ModalBottomSheetExample> createState() => _ModalBottomSheetExampleState(); | ||
} | ||
|
||
class _ModalBottomSheetExampleState extends State<ModalBottomSheetExample> { | ||
Set<AnimationStyles> _animationStyleSelection = <AnimationStyles>{AnimationStyles.defaultStyle}; | ||
AnimationStyle? _animationStyle; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Center( | ||
child: Column( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
children: <Widget>[ | ||
SegmentedButton<AnimationStyles>( | ||
selected: _animationStyleSelection, | ||
onSelectionChanged: (Set<AnimationStyles> styles) { | ||
setState(() { | ||
_animationStyle = switch (styles.first) { | ||
AnimationStyles.defaultStyle => null, | ||
AnimationStyles.custom => AnimationStyle( | ||
duration: const Duration(seconds: 3), | ||
reverseDuration: const Duration(seconds: 1), | ||
), | ||
AnimationStyles.none => AnimationStyle.noAnimation, | ||
}; | ||
_animationStyleSelection = styles; | ||
}); | ||
}, | ||
segments: animationStyleSegments | ||
.map<ButtonSegment<AnimationStyles>>(((AnimationStyles, String) shirt) { | ||
return ButtonSegment<AnimationStyles>(value: shirt.$1, label: Text(shirt.$2)); | ||
}) | ||
.toList(), | ||
), | ||
const SizedBox(height: 10), | ||
ElevatedButton( | ||
child: const Text('showModalBottomSheet'), | ||
onPressed: () { | ||
showModalBottomSheet<void>( | ||
context: context, | ||
sheetAnimationStyle: _animationStyle, | ||
builder: (BuildContext context) { | ||
return SizedBox.expand( | ||
child: Center( | ||
child: Column( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
mainAxisSize: MainAxisSize.min, | ||
children: <Widget>[ | ||
const Text('Modal bottom sheet'), | ||
ElevatedButton( | ||
child: const Text('Close'), | ||
onPressed: () => Navigator.pop(context), | ||
), | ||
], | ||
), | ||
), | ||
); | ||
}, | ||
); | ||
}, | ||
), | ||
], | ||
), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
examples/api/lib/material/scaffold/scaffold_state.show_bottom_sheet.1.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// 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 sample for [ScaffoldState.showBottomSheet]. | ||
void main() => runApp(const ShowBottomSheetExampleApp()); | ||
|
||
class ShowBottomSheetExampleApp extends StatelessWidget { | ||
const ShowBottomSheetExampleApp({super.key}); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return MaterialApp( | ||
home: Scaffold( | ||
appBar: AppBar(title: const Text('ScaffoldState BottomSheet Sample')), | ||
body: const ShowBottomSheetExample(), | ||
), | ||
); | ||
} | ||
} | ||
|
||
enum AnimationStyles { defaultStyle, custom, none } | ||
const List<(AnimationStyles, String)> animationStyleSegments = <(AnimationStyles, String)>[ | ||
(AnimationStyles.defaultStyle, 'Default'), | ||
(AnimationStyles.custom, 'Custom'), | ||
(AnimationStyles.none, 'None'), | ||
]; | ||
|
||
class ShowBottomSheetExample extends StatefulWidget { | ||
const ShowBottomSheetExample({super.key}); | ||
|
||
@override | ||
State<ShowBottomSheetExample> createState() => _ShowBottomSheetExampleState(); | ||
} | ||
|
||
class _ShowBottomSheetExampleState extends State<ShowBottomSheetExample> { | ||
Set<AnimationStyles> _animationStyleSelection = <AnimationStyles>{AnimationStyles.defaultStyle}; | ||
AnimationStyle? _animationStyle; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Center( | ||
child: Column( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
children: <Widget>[ | ||
SegmentedButton<AnimationStyles>( | ||
selected: _animationStyleSelection, | ||
onSelectionChanged: (Set<AnimationStyles> styles) { | ||
setState(() { | ||
_animationStyle = switch (styles.first) { | ||
AnimationStyles.defaultStyle => null, | ||
AnimationStyles.custom => AnimationStyle( | ||
duration: const Duration(seconds: 3), | ||
reverseDuration: const Duration(seconds: 1), | ||
), | ||
AnimationStyles.none => AnimationStyle.noAnimation, | ||
}; | ||
_animationStyleSelection = styles; | ||
}); | ||
}, | ||
segments: animationStyleSegments | ||
.map<ButtonSegment<AnimationStyles>>(((AnimationStyles, String) shirt) { | ||
return ButtonSegment<AnimationStyles>(value: shirt.$1, label: Text(shirt.$2)); | ||
}) | ||
.toList(), | ||
), | ||
const SizedBox(height: 10), | ||
ElevatedButton( | ||
child: const Text('showBottomSheet'), | ||
onPressed: () { | ||
Scaffold.of(context).showBottomSheet( | ||
sheetAnimationStyle: _animationStyle, | ||
(BuildContext context) { | ||
return SizedBox( | ||
height: 200, | ||
child: Center( | ||
child: Column( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
mainAxisSize: MainAxisSize.min, | ||
children: <Widget>[ | ||
const Text('BottomSheet'), | ||
ElevatedButton( | ||
child: const Text('Close'), | ||
onPressed: () { | ||
Navigator.pop(context); | ||
}, | ||
), | ||
], | ||
), | ||
), | ||
); | ||
}, | ||
); | ||
}, | ||
), | ||
], | ||
), | ||
); | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
examples/api/test/material/bottom_sheet/show_bottom_sheet.0_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// 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/material/bottom_sheet/show_bottom_sheet.0.dart' as example; | ||
import 'package:flutter_test/flutter_test.dart'; | ||
|
||
void main() { | ||
testWidgets('Bottom sheet animation can be customized using AnimationStyle', (WidgetTester tester) async { | ||
await tester.pumpWidget( | ||
const example.BottomSheetExampleApp(), | ||
); | ||
|
||
// Show the bottom sheet with default animation style. | ||
await tester.tap(find.widgetWithText(ElevatedButton, 'showBottomSheet')); | ||
await tester.pump(); | ||
// Advance the animation by 1/2 of the default forward duration. | ||
await tester.pump(const Duration(milliseconds: 125)); | ||
|
||
// The bottom sheet is partially visible. | ||
expect(tester.getTopLeft(find.byType(BottomSheet)).dy, closeTo(178.0, 0.1)); | ||
|
||
// Advance the animation by 1/2 of the default forward duration. | ||
await tester.pump(const Duration(milliseconds: 125)); | ||
|
||
// The bottom sheet is fully visible. | ||
expect(tester.getTopLeft(find.byType(BottomSheet)).dy, equals(56.0)); | ||
|
||
// Dismiss the bottom sheet. | ||
await tester.tap(find.widgetWithText(ElevatedButton, 'Close')); | ||
await tester.pumpAndSettle(); | ||
|
||
// Select custom animation style. | ||
await tester.tap(find.text('Custom')); | ||
await tester.pumpAndSettle(); | ||
|
||
// Show the bottom sheet with custom animation style. | ||
await tester.tap(find.widgetWithText(ElevatedButton, 'showBottomSheet')); | ||
await tester.pump(); | ||
// Advance the animation by 1/2 of the custom forward duration. | ||
await tester.pump(const Duration(milliseconds: 1500)); | ||
|
||
// The bottom sheet is partially visible. | ||
expect(tester.getTopLeft(find.byType(BottomSheet)).dy, closeTo(178.0, 0.1)); | ||
|
||
// Advance the animation by 1/2 of the custom forward duration. | ||
await tester.pump(const Duration(milliseconds: 1500)); | ||
|
||
// The bottom sheet is fully visible. | ||
expect(tester.getTopLeft(find.byType(BottomSheet)).dy, equals(56.0)); | ||
|
||
// Dismiss the bottom sheet. | ||
await tester.tap(find.widgetWithText(ElevatedButton, 'Close')); | ||
await tester.pumpAndSettle(); | ||
|
||
// Select no animation style. | ||
await tester.tap(find.text('None')); | ||
await tester.pumpAndSettle(); | ||
|
||
// Show the bottom sheet with no animation style. | ||
await tester.tap(find.widgetWithText(ElevatedButton, 'showBottomSheet')); | ||
await tester.pump(); | ||
expect(tester.getTopLeft(find.byType(BottomSheet)).dy, equals(56.0)); | ||
}); | ||
} |
Oops, something went wrong.