CupertinoAlertDialog should not create ScrollController on every build, if null values are passed in constructor. (#134075)
Relanding of https://github.com/flutter/flutter/pull/134071 Verified failed tests succeeded now:
This commit is contained in:
parent
a863ad6e76
commit
cc95ace32c
@ -188,7 +188,7 @@ bool _isInAccessibilityMode(BuildContext context) {
|
|||||||
/// * [CupertinoDialogAction], which is an iOS-style dialog button.
|
/// * [CupertinoDialogAction], which is an iOS-style dialog button.
|
||||||
/// * [AlertDialog], a Material Design alert dialog.
|
/// * [AlertDialog], a Material Design alert dialog.
|
||||||
/// * <https://developer.apple.com/ios/human-interface-guidelines/views/alerts/>
|
/// * <https://developer.apple.com/ios/human-interface-guidelines/views/alerts/>
|
||||||
class CupertinoAlertDialog extends StatelessWidget {
|
class CupertinoAlertDialog extends StatefulWidget {
|
||||||
/// Creates an iOS-style alert dialog.
|
/// Creates an iOS-style alert dialog.
|
||||||
///
|
///
|
||||||
/// The [actions] must not be null.
|
/// The [actions] must not be null.
|
||||||
@ -233,9 +233,6 @@ class CupertinoAlertDialog extends StatelessWidget {
|
|||||||
/// section when there are many actions.
|
/// section when there are many actions.
|
||||||
final ScrollController? scrollController;
|
final ScrollController? scrollController;
|
||||||
|
|
||||||
ScrollController get _effectiveScrollController =>
|
|
||||||
scrollController ?? ScrollController();
|
|
||||||
|
|
||||||
/// A scroll controller that can be used to control the scrolling of the
|
/// A scroll controller that can be used to control the scrolling of the
|
||||||
/// actions in the dialog.
|
/// actions in the dialog.
|
||||||
///
|
///
|
||||||
@ -247,37 +244,49 @@ class CupertinoAlertDialog extends StatelessWidget {
|
|||||||
/// section when it is long.
|
/// section when it is long.
|
||||||
final ScrollController? actionScrollController;
|
final ScrollController? actionScrollController;
|
||||||
|
|
||||||
ScrollController get _effectiveActionScrollController =>
|
|
||||||
actionScrollController ?? ScrollController();
|
|
||||||
|
|
||||||
/// {@macro flutter.material.dialog.insetAnimationDuration}
|
/// {@macro flutter.material.dialog.insetAnimationDuration}
|
||||||
final Duration insetAnimationDuration;
|
final Duration insetAnimationDuration;
|
||||||
|
|
||||||
/// {@macro flutter.material.dialog.insetAnimationCurve}
|
/// {@macro flutter.material.dialog.insetAnimationCurve}
|
||||||
final Curve insetAnimationCurve;
|
final Curve insetAnimationCurve;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CupertinoAlertDialog> createState() => _CupertinoAlertDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CupertinoAlertDialogState extends State<CupertinoAlertDialog> {
|
||||||
|
ScrollController? _backupScrollController;
|
||||||
|
|
||||||
|
ScrollController? _backupActionScrollController;
|
||||||
|
|
||||||
|
ScrollController get _effectiveScrollController =>
|
||||||
|
widget.scrollController ?? (_backupScrollController ??= ScrollController());
|
||||||
|
|
||||||
|
ScrollController get _effectiveActionScrollController =>
|
||||||
|
widget.actionScrollController ?? (_backupActionScrollController ??= ScrollController());
|
||||||
|
|
||||||
Widget _buildContent(BuildContext context) {
|
Widget _buildContent(BuildContext context) {
|
||||||
final double textScaleFactor = MediaQuery.textScalerOf(context).textScaleFactor;
|
final double textScaleFactor = MediaQuery.textScalerOf(context).textScaleFactor;
|
||||||
|
|
||||||
final List<Widget> children = <Widget>[
|
final List<Widget> children = <Widget>[
|
||||||
if (title != null || content != null)
|
if (widget.title != null || widget.content != null)
|
||||||
Flexible(
|
Flexible(
|
||||||
flex: 3,
|
flex: 3,
|
||||||
child: _CupertinoAlertContentSection(
|
child: _CupertinoAlertContentSection(
|
||||||
title: title,
|
title: widget.title,
|
||||||
message: content,
|
message: widget.content,
|
||||||
scrollController: _effectiveScrollController,
|
scrollController: _effectiveScrollController,
|
||||||
titlePadding: EdgeInsets.only(
|
titlePadding: EdgeInsets.only(
|
||||||
left: _kDialogEdgePadding,
|
left: _kDialogEdgePadding,
|
||||||
right: _kDialogEdgePadding,
|
right: _kDialogEdgePadding,
|
||||||
bottom: content == null ? _kDialogEdgePadding : 1.0,
|
bottom: widget.content == null ? _kDialogEdgePadding : 1.0,
|
||||||
top: _kDialogEdgePadding * textScaleFactor,
|
top: _kDialogEdgePadding * textScaleFactor,
|
||||||
),
|
),
|
||||||
messagePadding: EdgeInsets.only(
|
messagePadding: EdgeInsets.only(
|
||||||
left: _kDialogEdgePadding,
|
left: _kDialogEdgePadding,
|
||||||
right: _kDialogEdgePadding,
|
right: _kDialogEdgePadding,
|
||||||
bottom: _kDialogEdgePadding * textScaleFactor,
|
bottom: _kDialogEdgePadding * textScaleFactor,
|
||||||
top: title == null ? _kDialogEdgePadding : 1.0,
|
top: widget.title == null ? _kDialogEdgePadding : 1.0,
|
||||||
),
|
),
|
||||||
titleTextStyle: _kCupertinoDialogTitleStyle.copyWith(
|
titleTextStyle: _kCupertinoDialogTitleStyle.copyWith(
|
||||||
color: CupertinoDynamicColor.resolve(CupertinoColors.label, context),
|
color: CupertinoDynamicColor.resolve(CupertinoColors.label, context),
|
||||||
@ -303,10 +312,10 @@ class CupertinoAlertDialog extends StatelessWidget {
|
|||||||
Widget actionSection = Container(
|
Widget actionSection = Container(
|
||||||
height: 0.0,
|
height: 0.0,
|
||||||
);
|
);
|
||||||
if (actions.isNotEmpty) {
|
if (widget.actions.isNotEmpty) {
|
||||||
actionSection = _CupertinoAlertActionSection(
|
actionSection = _CupertinoAlertActionSection(
|
||||||
scrollController: _effectiveActionScrollController,
|
scrollController: _effectiveActionScrollController,
|
||||||
children: actions,
|
children: widget.actions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,8 +339,8 @@ class CupertinoAlertDialog extends StatelessWidget {
|
|||||||
return AnimatedPadding(
|
return AnimatedPadding(
|
||||||
padding: MediaQuery.viewInsetsOf(context) +
|
padding: MediaQuery.viewInsetsOf(context) +
|
||||||
const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
|
const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
|
||||||
duration: insetAnimationDuration,
|
duration: widget.insetAnimationDuration,
|
||||||
curve: insetAnimationCurve,
|
curve: widget.insetAnimationCurve,
|
||||||
child: MediaQuery.removeViewInsets(
|
child: MediaQuery.removeViewInsets(
|
||||||
removeLeft: true,
|
removeLeft: true,
|
||||||
removeTop: true,
|
removeTop: true,
|
||||||
@ -368,6 +377,13 @@ class CupertinoAlertDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_backupScrollController?.dispose();
|
||||||
|
_backupActionScrollController?.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rounded rectangle surface that looks like an iOS popup surface, e.g., alert dialog
|
/// Rounded rectangle surface that looks like an iOS popup surface, e.g., alert dialog
|
||||||
|
@ -2664,7 +2664,7 @@ void main() {
|
|||||||
okNode.dispose();
|
okNode.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Adaptive AlertDialog shows correct widget on each platform', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('Adaptive AlertDialog shows correct widget on each platform', (WidgetTester tester) async {
|
||||||
final AlertDialog dialog = AlertDialog.adaptive(
|
final AlertDialog dialog = AlertDialog.adaptive(
|
||||||
content: Container(
|
content: Container(
|
||||||
height: 5000.0,
|
height: 5000.0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user