add directionality to CupertinoDialog (#167403)

Fixes `CupertinoDialog` not respecting Directionality for actions
Issue refers to AlertDIalog.adaptive, but I have found that problem
occurs only in `CupertinoDialog`.

## Related Issues
* Fixes [Dialog actions do not respect Directionality
#166880](https://github.com/flutter/flutter/issues/166880)

## Tests
Added 1 test

## 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:
Tosemite 2025-04-28 23:11:12 +05:00 committed by GitHub
parent bee65f3a4f
commit 9218243c61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 13 deletions

View File

@ -2307,23 +2307,31 @@ class _AlertDialogActionsLayout extends MultiChildRenderObjectWidget {
@override
RenderObject createRenderObject(BuildContext context) {
return _RenderAlertDialogActionsLayout(dividerThickness: _dividerThickness);
return _RenderAlertDialogActionsLayout(
dividerThickness: _dividerThickness,
textDirection: Directionality.of(context),
);
}
@override
void updateRenderObject(BuildContext context, _RenderAlertDialogActionsLayout renderObject) {
renderObject.dividerThickness = _dividerThickness;
renderObject
..dividerThickness = _dividerThickness
..textDirection = Directionality.of(context);
}
}
class _RenderAlertDialogActionsLayout extends RenderFlex {
_RenderAlertDialogActionsLayout({List<RenderBox>? children, required double dividerThickness})
: _dividerThickness = dividerThickness,
super(
direction: Axis.vertical,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
) {
_RenderAlertDialogActionsLayout({
List<RenderBox>? children,
required double dividerThickness,
super.textDirection,
}) : _dividerThickness = dividerThickness,
super(
direction: Axis.vertical,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
) {
addAll(children);
}
@ -2405,12 +2413,17 @@ class _RenderAlertDialogActionsLayout extends RenderFlex {
final double height = getMinIntrinsicHeight(overallWidth);
size = Size(overallWidth, height);
final bool ltr = textDirection == TextDirection.ltr;
RenderBox slot = firstChild!;
double x = 0;
double x = ltr ? 0 : (overallWidth - slotWidth);
while (true) {
slot.layout(BoxConstraints.tight(Size(slotWidth, height)), parentUsesSize: true);
(slot.parentData! as FlexParentData).offset = Offset(x, 0);
x += slot.size.width;
if (ltr) {
x += slot.size.width;
} else {
x -= slot.size.width;
}
final RenderBox? divider = childAfter(slot);
if (divider == null) {
@ -2418,8 +2431,11 @@ class _RenderAlertDialogActionsLayout extends RenderFlex {
}
divider.layout(BoxConstraints.tight(Size(dividerThickness, height)));
(divider.parentData! as FlexParentData).offset = Offset(x, 0);
x += dividerThickness;
if (ltr) {
x += dividerThickness;
} else {
x -= dividerThickness;
}
slot = childAfter(divider)!;
}
}

View File

@ -2036,6 +2036,33 @@ void main() {
expect(elements.length, 1, reason: 'No DecoratedBox matches the specified criteria.');
});
testWidgets('Check for Directionality', (WidgetTester tester) async {
Future<void> pumpWidget({required bool isLTR}) async {
await tester.pumpWidget(
CupertinoApp(
home: Directionality(
textDirection: isLTR ? TextDirection.ltr : TextDirection.rtl,
child: const CupertinoAlertDialog(
actions: <CupertinoDialogAction>[
CupertinoDialogAction(isDefaultAction: true, child: Text('No')),
CupertinoDialogAction(child: Text('Yes')),
],
),
),
),
);
}
await pumpWidget(isLTR: true);
Offset yesButton = tester.getCenter(find.text('Yes'));
Offset noButton = tester.getCenter(find.text('No'));
expect(yesButton.dx > noButton.dx, true);
await pumpWidget(isLTR: false);
yesButton = tester.getCenter(find.text('Yes'));
noButton = tester.getCenter(find.text('No'));
expect(yesButton.dx > noButton.dx, false);
});
}
RenderBox findActionButtonRenderBoxByTitle(WidgetTester tester, String title) {
@ -2124,6 +2151,7 @@ class _RestorableDialogTestWidget extends StatelessWidget {
// The `theme` will be applied to the app and determines the background.
class TestScaffoldApp extends StatefulWidget {
const TestScaffoldApp({super.key, required this.theme, required this.dialog});
final CupertinoThemeData theme;
final Widget dialog;