Unverified Commit cc95ace3 authored by Polina Cherkasova's avatar Polina Cherkasova Committed by GitHub

CupertinoAlertDialog should not create ScrollController on every build, if...

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:
parent a863ad6e
......@@ -188,7 +188,7 @@ bool _isInAccessibilityMode(BuildContext context) {
/// * [CupertinoDialogAction], which is an iOS-style dialog button.
/// * [AlertDialog], a Material Design alert dialog.
/// * <https://developer.apple.com/ios/human-interface-guidelines/views/alerts/>
class CupertinoAlertDialog extends StatelessWidget {
class CupertinoAlertDialog extends StatefulWidget {
/// Creates an iOS-style alert dialog.
///
/// The [actions] must not be null.
......@@ -233,9 +233,6 @@ class CupertinoAlertDialog extends StatelessWidget {
/// section when there are many actions.
final ScrollController? scrollController;
ScrollController get _effectiveScrollController =>
scrollController ?? ScrollController();
/// A scroll controller that can be used to control the scrolling of the
/// actions in the dialog.
///
......@@ -247,37 +244,49 @@ class CupertinoAlertDialog extends StatelessWidget {
/// section when it is long.
final ScrollController? actionScrollController;
ScrollController get _effectiveActionScrollController =>
actionScrollController ?? ScrollController();
/// {@macro flutter.material.dialog.insetAnimationDuration}
final Duration insetAnimationDuration;
/// {@macro flutter.material.dialog.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) {
final double textScaleFactor = MediaQuery.textScalerOf(context).textScaleFactor;
final List<Widget> children = <Widget>[
if (title != null || content != null)
if (widget.title != null || widget.content != null)
Flexible(
flex: 3,
child: _CupertinoAlertContentSection(
title: title,
message: content,
title: widget.title,
message: widget.content,
scrollController: _effectiveScrollController,
titlePadding: EdgeInsets.only(
left: _kDialogEdgePadding,
right: _kDialogEdgePadding,
bottom: content == null ? _kDialogEdgePadding : 1.0,
bottom: widget.content == null ? _kDialogEdgePadding : 1.0,
top: _kDialogEdgePadding * textScaleFactor,
),
messagePadding: EdgeInsets.only(
left: _kDialogEdgePadding,
right: _kDialogEdgePadding,
bottom: _kDialogEdgePadding * textScaleFactor,
top: title == null ? _kDialogEdgePadding : 1.0,
top: widget.title == null ? _kDialogEdgePadding : 1.0,
),
titleTextStyle: _kCupertinoDialogTitleStyle.copyWith(
color: CupertinoDynamicColor.resolve(CupertinoColors.label, context),
......@@ -303,10 +312,10 @@ class CupertinoAlertDialog extends StatelessWidget {
Widget actionSection = Container(
height: 0.0,
);
if (actions.isNotEmpty) {
if (widget.actions.isNotEmpty) {
actionSection = _CupertinoAlertActionSection(
scrollController: _effectiveActionScrollController,
children: actions,
children: widget.actions,
);
}
......@@ -330,8 +339,8 @@ class CupertinoAlertDialog extends StatelessWidget {
return AnimatedPadding(
padding: MediaQuery.viewInsetsOf(context) +
const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
duration: insetAnimationDuration,
curve: insetAnimationCurve,
duration: widget.insetAnimationDuration,
curve: widget.insetAnimationCurve,
child: MediaQuery.removeViewInsets(
removeLeft: 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
......
......@@ -2664,7 +2664,7 @@ void main() {
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(
content: Container(
height: 5000.0,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment