Unverified Commit 854bbb90 authored by Kostia Sokolovskyi's avatar Kostia Sokolovskyi Committed by GitHub

Fix memory leak in CupertinoActionSheet (#134885)

parent 60fae58a
...@@ -474,7 +474,7 @@ class CupertinoPopupSurface extends StatelessWidget { ...@@ -474,7 +474,7 @@ class CupertinoPopupSurface extends StatelessWidget {
/// ///
/// * [CupertinoActionSheetAction], which is an iOS-style action sheet button. /// * [CupertinoActionSheetAction], which is an iOS-style action sheet button.
/// * <https://developer.apple.com/design/human-interface-guidelines/ios/views/action-sheets/> /// * <https://developer.apple.com/design/human-interface-guidelines/ios/views/action-sheets/>
class CupertinoActionSheet extends StatelessWidget { class CupertinoActionSheet extends StatefulWidget {
/// Creates an iOS-style action sheet. /// Creates an iOS-style action sheet.
/// ///
/// An action sheet must have a non-null value for at least one of the /// An action sheet must have a non-null value for at least one of the
...@@ -520,30 +520,46 @@ class CupertinoActionSheet extends StatelessWidget { ...@@ -520,30 +520,46 @@ class CupertinoActionSheet extends StatelessWidget {
/// short. /// short.
final ScrollController? messageScrollController; final ScrollController? messageScrollController;
ScrollController get _effectiveMessageScrollController =>
messageScrollController ?? 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 action sheet. /// [actions] in the action sheet.
/// ///
/// This attribute is typically not needed. /// This attribute is typically not needed.
final ScrollController? actionScrollController; final ScrollController? actionScrollController;
ScrollController get _effectiveActionScrollController =>
actionScrollController ?? ScrollController();
/// The optional cancel button that is grouped separately from the other /// The optional cancel button that is grouped separately from the other
/// actions. /// actions.
/// ///
/// Typically this is an [CupertinoActionSheetAction] widget. /// Typically this is an [CupertinoActionSheetAction] widget.
final Widget? cancelButton; final Widget? cancelButton;
@override
State<CupertinoActionSheet> createState() => _CupertinoActionSheetState();
}
class _CupertinoActionSheetState extends State<CupertinoActionSheet> {
ScrollController? _backupMessageScrollController;
ScrollController? _backupActionScrollController;
ScrollController get _effectiveMessageScrollController =>
widget.messageScrollController ?? (_backupMessageScrollController ??= ScrollController());
ScrollController get _effectiveActionScrollController =>
widget.actionScrollController ?? (_backupActionScrollController ??= ScrollController());
@override
void dispose() {
_backupMessageScrollController?.dispose();
_backupActionScrollController?.dispose();
super.dispose();
}
Widget _buildContent(BuildContext context) { Widget _buildContent(BuildContext context) {
final List<Widget> content = <Widget>[]; final List<Widget> content = <Widget>[];
if (title != null || message != null) { if (widget.title != null || widget.message != null) {
final Widget titleSection = _CupertinoAlertContentSection( final Widget titleSection = _CupertinoAlertContentSection(
title: title, title: widget.title,
message: message, message: widget.message,
scrollController: _effectiveMessageScrollController, scrollController: _effectiveMessageScrollController,
titlePadding: const EdgeInsets.only( titlePadding: const EdgeInsets.only(
left: _kActionSheetContentHorizontalPadding, left: _kActionSheetContentHorizontalPadding,
...@@ -554,13 +570,13 @@ class CupertinoActionSheet extends StatelessWidget { ...@@ -554,13 +570,13 @@ class CupertinoActionSheet extends StatelessWidget {
messagePadding: EdgeInsets.only( messagePadding: EdgeInsets.only(
left: _kActionSheetContentHorizontalPadding, left: _kActionSheetContentHorizontalPadding,
right: _kActionSheetContentHorizontalPadding, right: _kActionSheetContentHorizontalPadding,
bottom: title == null ? _kActionSheetContentVerticalPadding : 22.0, bottom: widget.title == null ? _kActionSheetContentVerticalPadding : 22.0,
top: title == null ? _kActionSheetContentVerticalPadding : 0.0, top: widget.title == null ? _kActionSheetContentVerticalPadding : 0.0,
), ),
titleTextStyle: message == null titleTextStyle: widget.message == null
? _kActionSheetContentStyle ? _kActionSheetContentStyle
: _kActionSheetContentStyle.copyWith(fontWeight: FontWeight.w600), : _kActionSheetContentStyle.copyWith(fontWeight: FontWeight.w600),
messageTextStyle: title == null messageTextStyle: widget.title == null
? _kActionSheetContentStyle.copyWith(fontWeight: FontWeight.w600) ? _kActionSheetContentStyle.copyWith(fontWeight: FontWeight.w600)
: _kActionSheetContentStyle, : _kActionSheetContentStyle,
additionalPaddingBetweenTitleAndMessage: const EdgeInsets.only(top: 8.0), additionalPaddingBetweenTitleAndMessage: const EdgeInsets.only(top: 8.0),
...@@ -579,26 +595,26 @@ class CupertinoActionSheet extends StatelessWidget { ...@@ -579,26 +595,26 @@ class CupertinoActionSheet extends StatelessWidget {
} }
Widget _buildActions() { Widget _buildActions() {
if (actions == null || actions!.isEmpty) { if (widget.actions == null || widget.actions!.isEmpty) {
return Container( return Container(
height: 0.0, height: 0.0,
); );
} }
return _CupertinoAlertActionSection( return _CupertinoAlertActionSection(
scrollController: _effectiveActionScrollController, scrollController: _effectiveActionScrollController,
hasCancelButton: cancelButton != null, hasCancelButton: widget.cancelButton != null,
isActionSheet: true, isActionSheet: true,
children: actions!, children: widget.actions!,
); );
} }
Widget _buildCancelButton() { Widget _buildCancelButton() {
final double cancelPadding = (actions != null || message != null || title != null) final double cancelPadding = (widget.actions != null || widget.message != null || widget.title != null)
? _kActionSheetCancelButtonPadding : 0.0; ? _kActionSheetCancelButtonPadding : 0.0;
return Padding( return Padding(
padding: EdgeInsets.only(top: cancelPadding), padding: EdgeInsets.only(top: cancelPadding),
child: _CupertinoActionSheetCancelButton( child: _CupertinoActionSheetCancelButton(
child: cancelButton, child: widget.cancelButton,
), ),
); );
} }
...@@ -621,7 +637,7 @@ class CupertinoActionSheet extends StatelessWidget { ...@@ -621,7 +637,7 @@ class CupertinoActionSheet extends StatelessWidget {
), ),
), ),
), ),
if (cancelButton != null) _buildCancelButton(), if (widget.cancelButton != null) _buildCancelButton(),
]; ];
final Orientation orientation = MediaQuery.orientationOf(context); final Orientation orientation = MediaQuery.orientationOf(context);
......
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