Fix: Update CupertinoSheetRoute transition rounded corner (#163700)
Fix: Update CupertinoSheetRoute transition rounded corner fixes: #163334 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing.
This commit is contained in:
parent
1cd6cb0cdc
commit
b44f717d57
@ -11,6 +11,19 @@ import 'interface_level.dart';
|
||||
import 'route.dart';
|
||||
import 'theme.dart';
|
||||
|
||||
// Smoothing factor applied to the device's top padding (which approximates the corner radius)
|
||||
// to achieve a smoother end to the corner radius animation. A value of 1.0 would use
|
||||
// the full top padding. Values less than 1.0 reduce the effective corner radius, improving
|
||||
// the animation's appearance. Determined through empirical testing.
|
||||
const double _kDeviceCornerRadiusSmoothingFactor = 0.9;
|
||||
|
||||
// Threshold in logical pixels. If the calculated device corner radius (after applying
|
||||
// the smoothing factor) is below this value, the corner radius transition animation will
|
||||
// start from zero. This prevents abrupt transitions for devices with small or negligible
|
||||
// corner radii. This value, combined with the smoothing factor, corresponds roughly
|
||||
// to double the targeted radius of 12. Determined through testing and visual inspection.
|
||||
const double _kRoundedDeviceCornersThreshold = 20.0;
|
||||
|
||||
// The distance from the top of the open sheet to the top of the screen, as a ratio
|
||||
// of the total height of the screen. Found from eyeballing a simulator running
|
||||
// iOS 18.0.
|
||||
@ -221,10 +234,15 @@ class CupertinoSheetTransition extends StatefulWidget {
|
||||
reverseCurve: reverseCurve,
|
||||
parent: secondaryAnimation,
|
||||
);
|
||||
final double deviceCornerRadius = MediaQuery.maybeViewPaddingOf(context)?.top ?? 0;
|
||||
|
||||
final double deviceCornerRadius =
|
||||
(MediaQuery.maybeViewPaddingOf(context)?.top ?? 0) * _kDeviceCornerRadiusSmoothingFactor;
|
||||
final bool roundedDeviceCorners = deviceCornerRadius > _kRoundedDeviceCornersThreshold;
|
||||
|
||||
final Animatable<BorderRadiusGeometry> decorationTween = Tween<BorderRadiusGeometry>(
|
||||
begin: BorderRadius.circular(deviceCornerRadius),
|
||||
begin: BorderRadius.vertical(
|
||||
top: Radius.circular(roundedDeviceCorners ? deviceCornerRadius : 0),
|
||||
),
|
||||
end: BorderRadius.circular(12),
|
||||
);
|
||||
|
||||
@ -262,7 +280,13 @@ class CupertinoSheetTransition extends StatefulWidget {
|
||||
animation: radiusAnimation,
|
||||
child: child,
|
||||
builder: (BuildContext context, Widget? child) {
|
||||
return ClipRRect(borderRadius: radiusAnimation.value, child: contrastedChild);
|
||||
return ClipRRect(
|
||||
borderRadius:
|
||||
!secondaryAnimation.isDismissed
|
||||
? radiusAnimation.value
|
||||
: BorderRadius.circular(0),
|
||||
child: contrastedChild,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../widgets/navigator_utils.dart';
|
||||
@ -745,6 +746,74 @@ void main() {
|
||||
expect(sheetNavBarHeight, lessThan(homeNavBardHeight));
|
||||
});
|
||||
|
||||
testWidgets('Previous route corner radius goes to same when sheet route is popped', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
final GlobalKey scaffoldKey = GlobalKey();
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: CupertinoPageScaffold(
|
||||
key: scaffoldKey,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
const Text('Page 1'),
|
||||
CupertinoButton(
|
||||
onPressed: () {
|
||||
Navigator.push<void>(
|
||||
scaffoldKey.currentContext!,
|
||||
CupertinoSheetRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoPageScaffold(
|
||||
child: GestureDetector(
|
||||
onTap: () => Navigator.pop(context),
|
||||
child: const Icon(Icons.arrow_back_ios),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text('Push Page 2'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.text('Page 1'), findsOneWidget);
|
||||
expect(
|
||||
tester
|
||||
.getTopLeft(
|
||||
find.ancestor(of: find.text('Page 1'), matching: find.byType(CupertinoPageScaffold)),
|
||||
)
|
||||
.dy,
|
||||
equals(0.0),
|
||||
);
|
||||
expect(find.byType(Icon), findsNothing);
|
||||
|
||||
await tester.tap(find.text('Push Page 2'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Previous page is still visible behind the new sheet.
|
||||
expect(find.text('Page 1'), findsOneWidget);
|
||||
final Offset pageOneOffset = tester.getTopLeft(
|
||||
find.ancestor(of: find.text('Page 1'), matching: find.byType(CupertinoPageScaffold)),
|
||||
);
|
||||
expect(pageOneOffset.dy, greaterThan(0.0));
|
||||
expect(pageOneOffset.dx, greaterThan(0.0));
|
||||
expect(find.byType(Icon), findsOneWidget);
|
||||
|
||||
// Pop Sheet Route
|
||||
await tester.tap(find.byType(Icon));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final Finder clipRRectFinder = find.byType(ClipRRect);
|
||||
final Rect clipRect = tester.getRect(clipRRectFinder);
|
||||
expect(clipRect.center, equals(const Offset(400, 300)));
|
||||
});
|
||||
|
||||
group('drag dismiss gesture', () {
|
||||
Widget dragGestureApp(GlobalKey homeScaffoldKey, GlobalKey sheetScaffoldKey) {
|
||||
return CupertinoApp(
|
||||
|
Loading…
x
Reference in New Issue
Block a user