[Cupertino] Exclude border for last action item in CupertinoContextMenu
(#92481)
This commit is contained in:
parent
4327b15b10
commit
a8f67ee37f
@ -9,10 +9,17 @@ import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'colors.dart';
|
||||
|
||||
// The scale of the child at the time that the CupertinoContextMenu opens.
|
||||
// This value was eyeballed from a physical device running iOS 13.1.2.
|
||||
const double _kOpenScale = 1.1;
|
||||
|
||||
const Color _borderColor = CupertinoDynamicColor.withBrightness(
|
||||
color: Color(0xFFA9A9AF),
|
||||
darkColor: Color(0xFF57585A),
|
||||
);
|
||||
|
||||
typedef _DismissCallback = void Function(
|
||||
BuildContext context,
|
||||
double scale,
|
||||
@ -1151,8 +1158,8 @@ class _ContextMenuSheet extends StatelessWidget {
|
||||
|
||||
// Get the children, whose order depends on orientation and
|
||||
// contextMenuLocation.
|
||||
List<Widget> get children {
|
||||
final Flexible menu = Flexible(
|
||||
List<Widget> getChildren(BuildContext context) {
|
||||
final Widget menu = Flexible(
|
||||
fit: FlexFit.tight,
|
||||
flex: 2,
|
||||
child: IntrinsicHeight(
|
||||
@ -1160,7 +1167,22 @@ class _ContextMenuSheet extends StatelessWidget {
|
||||
borderRadius: const BorderRadius.all(Radius.circular(13.0)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: actions,
|
||||
children: <Widget>[
|
||||
actions.first,
|
||||
for (Widget action in actions.skip(1))
|
||||
DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: CupertinoDynamicColor.resolve(_borderColor, context),
|
||||
width: 0.5,
|
||||
)
|
||||
),
|
||||
),
|
||||
position: DecorationPosition.foreground,
|
||||
child: action,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -1195,7 +1217,7 @@ class _ContextMenuSheet extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: children,
|
||||
children: getChildren(context),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -115,9 +115,6 @@ class _CupertinoContextMenuActionState extends State<CupertinoContextMenuAction>
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: _isPressed ? _kBackgroundColorPressed : _kBackgroundColor,
|
||||
border: const Border(
|
||||
bottom: BorderSide(color: _kBackgroundColorPressed),
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 16.0,
|
||||
|
@ -9,7 +9,6 @@ void main() {
|
||||
final TestWidgetsFlutterBinding binding =
|
||||
TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
|
||||
const double _kOpenScale = 1.1;
|
||||
|
||||
Widget _getChild() {
|
||||
return Container(
|
||||
width: 300.0,
|
||||
@ -66,6 +65,13 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
Finder _findStaticChildDecoration(WidgetTester tester) {
|
||||
return find.descendant(
|
||||
of: _findStatic(),
|
||||
matching: find.byType(DecoratedBox),
|
||||
);
|
||||
}
|
||||
|
||||
group('CupertinoContextMenu before and during opening', () {
|
||||
testWidgets('An unopened CupertinoContextMenu renders child in the same place as without', (WidgetTester tester) async {
|
||||
// Measure the child in the scene with no CupertinoContextMenu.
|
||||
@ -190,6 +196,65 @@ void main() {
|
||||
});
|
||||
|
||||
group('CupertinoContextMenu when open', () {
|
||||
testWidgets('Last action does not have border', (WidgetTester tester) async {
|
||||
final Widget child = _getChild();
|
||||
await tester.pumpWidget(CupertinoApp(
|
||||
home: CupertinoPageScaffold(
|
||||
child: Center(
|
||||
child: CupertinoContextMenu(
|
||||
actions: const <CupertinoContextMenuAction>[
|
||||
CupertinoContextMenuAction(
|
||||
child: Text('CupertinoContextMenuAction One'),
|
||||
),
|
||||
],
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Open the CupertinoContextMenu
|
||||
final TestGesture firstGesture = await tester.startGesture(tester.getCenter(find.byWidget(child)));
|
||||
await tester.pumpAndSettle();
|
||||
await firstGesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(_findStatic(), findsOneWidget);
|
||||
|
||||
expect(_findStaticChildDecoration(tester), findsNWidgets(1));
|
||||
|
||||
// Close the CupertinoContextMenu.
|
||||
await tester.tapAt(const Offset(1.0, 1.0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(_findStatic(), findsNothing);
|
||||
|
||||
await tester.pumpWidget(CupertinoApp(
|
||||
home: CupertinoPageScaffold(
|
||||
child: Center(
|
||||
child: CupertinoContextMenu(
|
||||
actions: const <CupertinoContextMenuAction>[
|
||||
CupertinoContextMenuAction(
|
||||
child: Text('CupertinoContextMenuAction One'),
|
||||
),
|
||||
CupertinoContextMenuAction(
|
||||
child: Text('CupertinoContextMenuAction Two'),
|
||||
),
|
||||
],
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Open the CupertinoContextMenu
|
||||
final TestGesture secondGesture = await tester.startGesture(tester.getCenter(find.byWidget(child)));
|
||||
await tester.pumpAndSettle();
|
||||
await secondGesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(_findStatic(), findsOneWidget);
|
||||
|
||||
expect(_findStaticChildDecoration(tester), findsNWidgets(3));
|
||||
});
|
||||
|
||||
testWidgets('Can close CupertinoContextMenu by background tap', (WidgetTester tester) async {
|
||||
final Widget child = _getChild();
|
||||
await tester.pumpWidget(_getContextMenu(child: child));
|
||||
|
Loading…
x
Reference in New Issue
Block a user