Add an example for CupertinoPopupSurface (#150357)

### Demo

https://github.com/flutter/flutter/assets/104349824/61cd4c96-e01e-4fad-b270-acd7bb55d995

### Related issue

Fixes https://github.com/flutter/flutter/issues/150353
This commit is contained in:
Huy 2024-06-25 18:20:34 +07:00 committed by GitHub
parent e250c655d1
commit 47689616a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 183 additions and 0 deletions

View file

@ -0,0 +1,105 @@
// 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/cupertino.dart';
/// Flutter code sample for [CupertinoPopupSurface].
void main() => runApp(const PopupSurfaceApp());
class PopupSurfaceApp extends StatelessWidget {
const PopupSurfaceApp({super.key});
@override
Widget build(BuildContext context) {
return const CupertinoApp(
home: PopupSurfaceExample(),
);
}
}
class PopupSurfaceExample extends StatefulWidget {
const PopupSurfaceExample({super.key});
@override
State<PopupSurfaceExample> createState() => _PopupSurfaceExampleState();
}
class _PopupSurfaceExampleState extends State<PopupSurfaceExample> {
bool _shouldPaintSurface = true;
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
const Text('Paint surface'),
const SizedBox(width: 16.0),
CupertinoSwitch(
value: _shouldPaintSurface,
onChanged: (bool value) => setState(() => _shouldPaintSurface = value),
),
],
),
CupertinoButton(
onPressed: () => _showPopupSurface(context),
child: const Text('Show popup'),
),
],
),
),
);
}
void _showPopupSurface(BuildContext context) {
showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) {
return CupertinoPopupSurface(
isSurfacePainted: _shouldPaintSurface,
child: Container(
height: 240,
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Expanded(
child: Container(
alignment: Alignment.center,
decoration: _shouldPaintSurface
? null
: BoxDecoration(
color: CupertinoTheme.of(context).scaffoldBackgroundColor,
borderRadius: BorderRadius.circular(8.0),
),
child: const Text('This is a popup surface.'),
),
),
const SizedBox(height: 8.0),
SizedBox(
width: double.infinity,
child: CupertinoButton(
color: _shouldPaintSurface
? null
: CupertinoTheme.of(context).scaffoldBackgroundColor,
onPressed: () => Navigator.pop(context),
child: const Text(
'Close',
style: TextStyle(color: CupertinoColors.systemBlue),
),
),
),
],
),
),
);
},
);
}
}

View file

@ -0,0 +1,70 @@
// 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/cupertino.dart';
import 'package:flutter_api_samples/cupertino/dialog/cupertino_popup_surface.0.dart'
as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('CupertinoPopupSurface displays expected widgets in init state',
(WidgetTester tester) async {
await tester.pumpWidget(const example.PopupSurfaceApp());
final Finder cupertinoButton = find.byType(CupertinoButton);
expect(cupertinoButton, findsOneWidget);
final Finder cupertinoSwitch = find.byType(CupertinoSwitch);
expect(cupertinoSwitch, findsOneWidget);
});
testWidgets('CupertinoPopupSurface is displayed with painted surface',
(WidgetTester tester) async {
await tester.pumpWidget(const example.PopupSurfaceApp());
// CupertinoSwitch is toggled on by default.
expect(tester.widget<CupertinoSwitch>(find.byType(CupertinoSwitch)).value, isTrue);
// Tap on the CupertinoButton to show the CupertinoPopupSurface.
await tester.tap(find.byType(CupertinoButton));
await tester.pumpAndSettle();
// Make sure CupertinoPopupSurface is showing.
final Finder cupertinoPopupSurface = find.byType(CupertinoPopupSurface);
expect(cupertinoPopupSurface, findsOneWidget);
// Confirm that CupertinoPopupSurface is painted with a ColoredBox.
final Finder coloredBox = find.descendant(
of: cupertinoPopupSurface,
matching: find.byType(ColoredBox),
);
expect(coloredBox, findsOneWidget);
});
testWidgets('CupertinoPopupSurface is displayed without painted surface',
(WidgetTester tester) async {
await tester.pumpWidget(const example.PopupSurfaceApp());
// Toggling off CupertinoSwitch and confirm its state.
final Finder cupertinoSwitch = find.byType(CupertinoSwitch);
await tester.tap(cupertinoSwitch);
await tester.pumpAndSettle();
expect(tester.widget<CupertinoSwitch>(cupertinoSwitch).value, isFalse);
// Tap on the CupertinoButton to show the CupertinoPopupSurface.
await tester.tap(find.byType(CupertinoButton));
await tester.pumpAndSettle();
// Make sure CupertinoPopupSurface is showing.
final Finder cupertinoPopupSurface = find.byType(CupertinoPopupSurface);
expect(cupertinoPopupSurface, findsOneWidget);
// Confirm that CupertinoPopupSurface is not painted with a ColoredBox.
final Finder coloredBox = find.descendant(
of: cupertinoPopupSurface,
matching: find.byType(ColoredBox),
);
expect(coloredBox, findsNothing);
});
}

View file

@ -419,6 +419,14 @@ class _CupertinoAlertDialogState extends State<CupertinoAlertDialog> {
/// Additionally, the white paint can be disabled to render a blurred rounded
/// rectangle without any color (similar to iOS's volume control popup).
///
/// {@tool dartpad}
/// This sample shows how to use a [CupertinoPopupSurface]. The [CupertinoPopupSurface]
/// shows a model popup from the bottom of the screen.
/// Toggling the switch to configure its surface color.
///
/// ** See code in examples/api/lib/cupertino/dialog/cupertino_popup_surface.0.dart **
/// {@end-tool}
///
/// See also:
///
/// * [CupertinoAlertDialog], which is a dialog with a title, content, and