Skip to content

Add more documentation around keep alive #168311

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 46 additions & 5 deletions packages/flutter/lib/src/widgets/automatic_keep_alive.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,23 @@ import 'sliver.dart';
///
/// To send these notifications, consider using [AutomaticKeepAliveClientMixin].
///
/// The [SliverChildBuilderDelegate] and [SliverChildListDelegate] delegates,
/// used with [SliverList] and [SliverGrid], as well as the scroll view
/// counterparts [ListView] and [GridView], have an `addAutomaticKeepAlives`
/// feature, which is enabled by default. This feature inserts
/// [AutomaticKeepAlive] widgets around each child, which in turn configure
/// [KeepAlive] widgets in response to [KeepAliveNotification]s.
///
/// The same `addAutomaticKeepAlives` feature is supported by
/// [TwoDimensionalChildBuilderDelegate] and [TwoDimensionalChildListDelegate].
///
/// {@tool dartpad}
/// This sample demonstrates how to use the [AutomaticKeepAlive] widget in
/// combination with the [AutomaticKeepAliveClientMixin] to selectively preserve
/// the state of individual items in a scrollable list.
///
/// Normally, widgets in a lazily built list like [ListView.builder] are
/// disposed of when they leave the visible area to save resources. This means
/// disposed of when they leave the visible area to maintain performance. This means
/// that any state inside a [StatefulWidget] would be lost unless explicitly
/// preserved.
///
Expand All @@ -50,6 +60,13 @@ import 'sliver.dart';
/// ** See code in examples/api/lib/widgets/keep_alive/automatic_keep_alive.0.dart **
/// {@end-tool}
///
/// See also:
///
/// * [AutomaticKeepAliveClientMixin], which is a mixin with convenience
/// methods for clients of [AutomaticKeepAlive]. Used with [State]
/// subclasses.
/// * [KeepAlive] which marks a child as needing to stay alive even when it's
/// in a lazy list that would otherwise remove it.
class AutomaticKeepAlive extends StatefulWidget {
/// Creates a widget that listens to [KeepAliveNotification]s and maintains a
/// [KeepAlive] widget appropriately.
Expand Down Expand Up @@ -354,8 +371,19 @@ class KeepAliveHandle extends ChangeNotifier {
}
}

/// A mixin with convenience methods for clients of [AutomaticKeepAlive]. Used
/// with [State] subclasses.
/// A mixin with convenience methods for clients of [AutomaticKeepAlive]. It is used
/// with [State] subclasses to manage keep-alive behavior in lazily built lists.
///
/// This mixin simplifies interaction with [AutomaticKeepAlive] by automatically
/// sending [KeepAliveNotification]s when necessary. Subclasses must implement
/// [wantKeepAlive] to indicate whether the widget should be kept alive and call
/// [updateKeepAlive] whenever its value changes.
///
/// The mixin internally manages a [KeepAliveHandle], which is used to notify
/// the nearest [AutomaticKeepAlive] ancestor of changes in keep-alive
/// requirements. [AutomaticKeepAlive] listens for [KeepAliveNotification]s sent
/// by this mixin and dynamically wraps the subtree in a [KeepAlive] widget to
/// preserve its state when it is no longer visible in the viewport.
///
/// Subclasses must implement [wantKeepAlive], and their [build] methods must
/// call `super.build` (though the return value should be ignored).
Expand All @@ -366,9 +394,20 @@ class KeepAliveHandle extends ChangeNotifier {
/// The type argument `T` is the type of the [StatefulWidget] subclass of the
/// [State] into which this class is being mixed.
///
/// The [SliverChildBuilderDelegate] and [SliverChildListDelegate] delegates,
/// used with [SliverList] and [SliverGrid], as well as the scroll view
/// counterparts [ListView] and [GridView], have an `addAutomaticKeepAlives`
/// feature, which is enabled by default. This feature inserts
/// [AutomaticKeepAlive] widgets around each child, which in turn configure
/// [KeepAlive] widgets in response to [KeepAliveNotification]s.
///
/// The same `addAutomaticKeepAlives` feature is supported by
/// [TwoDimensionalChildBuilderDelegate] and [TwoDimensionalChildListDelegate].
///
/// {@tool dartpad}
/// This example demonstrates how to use the [AutomaticKeepAliveClientMixin]
/// to keep the state of a widget alive even when it is scrolled out of view.
/// This example demonstrates how to use the
/// [AutomaticKeepAliveClientMixin] to keep the state of a widget alive even
/// when it is scrolled out of view.
///
/// ** See code in examples/api/lib/widgets/keep_alive/automatic_keep_alive_client_mixin.0.dart **
/// {@end-tool}
Expand All @@ -377,6 +416,8 @@ class KeepAliveHandle extends ChangeNotifier {
///
/// * [AutomaticKeepAlive], which listens to messages from this mixin.
/// * [KeepAliveNotification], the notifications sent by this mixin.
/// * [KeepAlive] which marks a child as needing to stay alive even when it's
/// in a lazy list that would otherwise remove it.
@optionalTypeArgs
mixin AutomaticKeepAliveClientMixin<T extends StatefulWidget> on State<T> {
KeepAliveHandle? _keepAliveHandle;
Expand Down
54 changes: 54 additions & 0 deletions packages/flutter/lib/src/widgets/scroll_delegate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,60 @@ class SliverChildBuilderDelegate extends SliverChildDelegate {
/// none of the children will ever try to keep themselves alive.
///
/// Defaults to true.
///
/// {@tool dartpad}
/// This sample demonstrates how to use the [AutomaticKeepAlive] widget in
/// combination with the [AutomaticKeepAliveClientMixin] to selectively preserve
/// the state of individual items in a scrollable list.
///
/// Normally, widgets in a lazily built list like [ListView.builder] are
/// disposed of when they leave the visible area to maintain performance. This means
/// that any state inside a [StatefulWidget] would be lost unless explicitly
/// preserved.
///
/// In this example, each list item is a [StatefulWidget] that includes a
/// counter and an increment button. To preserve the state of selected items
/// (based on their index), the [AutomaticKeepAlive] widget and
/// [AutomaticKeepAliveClientMixin] are used:
///
/// - The `wantKeepAlive` getter in the item’s state class returns true for
/// even-indexed items, indicating that their state should be preserved.
/// - For odd-indexed items, `wantKeepAlive` returns false, so their state is
/// not preserved when scrolled out of view.
///
/// ** See code in examples/api/lib/widgets/keep_alive/automatic_keep_alive.0.dart **
/// {@end-tool}
///
/// {@tool dartpad}
/// This sample demonstrates how to use the [KeepAlive] widget
/// to preserve the state of individual list items in a [ListView] when they are
/// scrolled out of view.
///
/// By default, [ListView.builder] only keeps the widgets currently visible in
/// the viewport alive. When an item scrolls out of view, it may be disposed to
/// free up resources. This can cause the state of [StatefulWidget]s to be lost
/// if not explicitly preserved.
///
/// In this example, each item in the list is a [StatefulWidget] that maintains
/// a counter. Tapping the "+" button increments the counter. To selectively
/// preserve the state, each item is wrapped in a [KeepAlive] widget, with the
/// keepAlive parameter set based on the item’s index:
///
/// - For even-indexed items, `keepAlive: true`, so their state is preserved
/// even when scrolled off-screen.
/// - For odd-indexed items, `keepAlive: false`, so their state is discarded
/// when they are no longer visible.
///
/// ** See code in examples/api/lib/widgets/keep_alive/keep_alive.0.dart **
/// {@end-tool}
///
/// * [AutomaticKeepAlive], which allows subtrees to request to be kept alive
/// in lazy lists.
/// * [AutomaticKeepAliveClientMixin], which is a mixin with convenience
/// methods for clients of [AutomaticKeepAlive]. Used with [State]
/// subclasses.
/// * [KeepAlive] which marks a child as needing to stay alive even when it's
/// in a lazy list that would otherwise remove it.
/// {@endtemplate}
final bool addAutomaticKeepAlives;

Expand Down
41 changes: 23 additions & 18 deletions packages/flutter/lib/src/widgets/sliver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1444,26 +1444,24 @@ class _SliverOffstageElement extends SingleChildRenderObjectElement {
/// Mark a child as needing to stay alive even when it's in a lazy list that
/// would otherwise remove it.
///
/// This widget is for use in a [RenderAbstractViewport]s, such as
/// [Viewport] or [TwoDimensionalViewport].
///
/// This widget is rarely used directly. The [SliverChildBuilderDelegate] and
/// [SliverChildListDelegate] delegates, used with [SliverList] and
/// [SliverGrid], as well as the scroll view counterparts [ListView] and
/// [GridView], have an `addAutomaticKeepAlives` feature, which is enabled by
/// default, and which causes [AutomaticKeepAlive] widgets to be inserted around
/// each child, causing [KeepAlive] widgets to be automatically added and
/// configured in response to [KeepAliveNotification]s.
///
/// The same `addAutomaticKeepAlives` feature is supported by the
/// This widget is used in [RenderAbstractViewport]s, such as [Viewport] or
/// [TwoDimensionalViewport], to manage the lifecycle of widgets that need to
/// remain alive even when scrolled out of view.
///
/// The [SliverChildBuilderDelegate] and [SliverChildListDelegate] delegates,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that some widgets in the framework already have this built-in is really valuable I think. Can we mention it above in the other areas where AutomaticKeepAlive comes up?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added it in Add mention of addAutomaticKeepAlives. It felt like having a template for it would be overkill, so I copied and pasted. Tell me what you think about it

/// used with [SliverList] and [SliverGrid], as well as the scroll view
/// counterparts [ListView] and [GridView], have an `addAutomaticKeepAlives`
/// feature, which is enabled by default. This feature inserts
/// [AutomaticKeepAlive] widgets around each child, which in turn configure
/// [KeepAlive] widgets in response to [KeepAliveNotification]s.
///
/// The same `addAutomaticKeepAlives` feature is supported by
/// [TwoDimensionalChildBuilderDelegate] and [TwoDimensionalChildListDelegate].
///
/// Therefore, to keep a widget alive, it is more common to use those
/// notifications than to directly deal with [KeepAlive] widgets.
///
/// In practice, the simplest way to deal with these notifications is to mix
/// [AutomaticKeepAliveClientMixin] into one's [State]. See the documentation
/// for that mixin class for details.
/// Keep-alive behavior can be managed by using [KeepAlive] directly or by
/// relying on notifications. For convenience, [AutomaticKeepAliveClientMixin]
/// may be mixed into a [State] subclass. Further details are available in the
/// documentation for [AutomaticKeepAliveClientMixin].
///
/// {@tool dartpad}
/// This sample demonstrates how to use the [KeepAlive] widget
Expand All @@ -1488,6 +1486,13 @@ class _SliverOffstageElement extends SingleChildRenderObjectElement {
/// ** See code in examples/api/lib/widgets/keep_alive/keep_alive.0.dart **
/// {@end-tool}
///
/// See also:
///
/// * [AutomaticKeepAlive], which allows subtrees to request to be kept alive
/// in lazy lists.
/// * [AutomaticKeepAliveClientMixin], which is a mixin with convenience
/// methods for clients of [AutomaticKeepAlive]. Used with [State]
/// subclasses.
class KeepAlive extends ParentDataWidget<KeepAliveParentDataMixin> {
/// Marks a child as needing to remain alive.
const KeepAlive({super.key, required this.keepAlive, required super.child});
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy