From c7ce24d345e0d773ce2bc85dd8af5543f1f9fc79 Mon Sep 17 00:00:00 2001 From: Taha Tesser Date: Wed, 13 Jul 2022 11:07:05 +0300 Subject: [PATCH] Update `ListTile` and `ListTile` based widget docs for Material usage (#107104) --- .../lib/src/material/checkbox_list_tile.dart | 29 ++++++++++++++++ .../flutter/lib/src/material/list_tile.dart | 28 ++++++++------- .../lib/src/material/radio_list_tile.dart | 30 ++++++++++++++++ .../lib/src/material/switch_list_tile.dart | 34 +++++++++++++++++-- 4 files changed, 107 insertions(+), 14 deletions(-) diff --git a/packages/flutter/lib/src/material/checkbox_list_tile.dart b/packages/flutter/lib/src/material/checkbox_list_tile.dart index 3c91c128aea..93ba8d9abb4 100644 --- a/packages/flutter/lib/src/material/checkbox_list_tile.dart +++ b/packages/flutter/lib/src/material/checkbox_list_tile.dart @@ -39,6 +39,35 @@ import 'theme_data.dart'; /// [secondary] widget is placed on the opposite side. This maps to the /// [ListTile.leading] and [ListTile.trailing] properties of [ListTile]. /// +/// This widget requires a [Material] widget ancestor in the tree to paint +/// itself on, which is typically provided by the app's [Scaffold]. +/// The [tileColor], and [selectedTileColor] are not painted by the +/// [CheckboxListTile] itself but by the [Material] widget ancestor. +/// In this case, one can wrap a [Material] widget around the [CheckboxListTile], +/// e.g.: +/// +/// {@tool snippet} +/// ```dart +/// Container( +/// color: Colors.green, +/// child: Material( +/// child: CheckboxListTile( +/// tileColor: Colors.red, +/// title: const Text('CheckboxListTile with red background'), +/// value: true, +/// onChanged:(bool? value) { }, +/// ), +/// ), +/// ) +/// ``` +/// {@end-tool} +/// +/// ## Performance considerations when wrapping [CheckboxListTile] with [Material] +/// +/// Wrapping a large number of [CheckboxListTile]s individually with [Material]s +/// is expensive. Consider only wrapping the [CheckboxListTile]s that require it +/// or include a common [Material] ancestor where possible. +/// /// To show the [CheckboxListTile] as disabled, pass null as the [onChanged] /// callback. /// diff --git a/packages/flutter/lib/src/material/list_tile.dart b/packages/flutter/lib/src/material/list_tile.dart index 9795398d957..0f123490239 100644 --- a/packages/flutter/lib/src/material/list_tile.dart +++ b/packages/flutter/lib/src/material/list_tile.dart @@ -87,28 +87,32 @@ enum ListTileControlAffinity { /// List tiles are typically used in [ListView]s, or arranged in [Column]s in /// [Drawer]s and [Card]s. /// -/// One ancestor must be a [Material] widget and typically this is -/// provided by the app's [Scaffold]. The [tileColor], -/// [selectedTileColor], [focusColor], and [hoverColor] are not -/// painted by the list tile itself but by the material widget -/// ancestor. This generally has no effect. However, if an opaque -/// widget, like `Container(color: Colors.white)`, is included in -/// between the [ListTile] and its [Material] ancestor, then the -/// opaque widget will obscure the material widget and its background -/// [tileColor], etc. If this a problem, one can wrap a [Material] -/// widget around the list tile, e.g.: +/// This widget requires a [Material] widget ancestor in the tree to paint +/// itself on, which is typically provided by the app's [Scaffold]. +/// The [tileColor], [selectedTileColor], [focusColor], and [hoverColor] +/// are not painted by the [ListTile] itself but by the [Material] widget +/// ancestor. In this case, one can wrap a [Material] widget around the +/// [ListTile], e.g.: /// +/// {@tool snippet} /// ```dart /// Container( /// color: Colors.green, -/// child: Material( +/// child: const Material( /// child: ListTile( -/// title: const Text('ListTile with red background'), +/// title: Text('ListTile with red background'), /// tileColor: Colors.red, /// ), /// ), /// ) /// ``` +/// {@end-tool} +/// +/// ## Performance considerations when wrapping [ListTile] with [Material] +/// +/// Wrapping a large number of [ListTile]s individually with [Material]s +/// is expensive. Consider only wrapping the [ListTile]s that require it +/// or include a common [Material] ancestor where possible. /// /// {@tool snippet} /// diff --git a/packages/flutter/lib/src/material/radio_list_tile.dart b/packages/flutter/lib/src/material/radio_list_tile.dart index 38797b0b3c2..ff180812e92 100644 --- a/packages/flutter/lib/src/material/radio_list_tile.dart +++ b/packages/flutter/lib/src/material/radio_list_tile.dart @@ -12,6 +12,7 @@ import 'theme_data.dart'; // Examples can assume: // void setState(VoidCallback fn) { } +// enum Meridiem { am, pm } /// A [ListTile] with a [Radio]. In other words, a radio button with a label. /// @@ -40,6 +41,35 @@ import 'theme_data.dart'; /// [secondary] widget is placed on the opposite side. This maps to the /// [ListTile.leading] and [ListTile.trailing] properties of [ListTile]. /// +/// This widget requires a [Material] widget ancestor in the tree to paint +/// itself on, which is typically provided by the app's [Scaffold]. +/// The [tileColor], and [selectedTileColor] are not painted by the +/// [RadioListTile] itself but by the [Material] widget ancestor. In this +/// case, one can wrap a [Material] widget around the [RadioListTile], e.g.: +/// +/// {@tool snippet} +/// ```dart +/// Container( +/// color: Colors.green, +/// child: Material( +/// child: RadioListTile( +/// tileColor: Colors.red, +/// title: const Text('AM'), +/// groupValue: Meridiem.am, +/// value: Meridiem.am, +/// onChanged:(Meridiem? value) { }, +/// ), +/// ), +/// ) +/// ``` +/// {@end-tool} +/// +/// ## Performance considerations when wrapping [RadioListTile] with [Material] +/// +/// Wrapping a large number of [RadioListTile]s individually with [Material]s +/// is expensive. Consider only wrapping the [RadioListTile]s that require it +/// or include a common [Material] ancestor where possible. +/// /// To show the [RadioListTile] as disabled, pass null as the [onChanged] /// callback. /// diff --git a/packages/flutter/lib/src/material/switch_list_tile.dart b/packages/flutter/lib/src/material/switch_list_tile.dart index 1ef05ee64a5..8180dd6f4ce 100644 --- a/packages/flutter/lib/src/material/switch_list_tile.dart +++ b/packages/flutter/lib/src/material/switch_list_tile.dart @@ -12,7 +12,7 @@ import 'theme_data.dart'; // Examples can assume: // void setState(VoidCallback fn) { } -// bool _isSelected; +// bool _isSelected = true; enum _SwitchListTileType { material, adaptive } @@ -47,6 +47,34 @@ enum _SwitchListTileType { material, adaptive } /// in the [ListTile.trailing] slot) which can be changed using [controlAffinity]. /// The [secondary] widget is placed in the [ListTile.leading] slot. /// +/// This widget requires a [Material] widget ancestor in the tree to paint +/// itself on, which is typically provided by the app's [Scaffold]. +/// The [tileColor], and [selectedTileColor] are not painted by the +/// [SwitchListTile] itself but by the [Material] widget ancestor. In this +/// case, one can wrap a [Material] widget around the [SwitchListTile], e.g.: +/// +/// {@tool snippet} +/// ```dart +/// Container( +/// color: Colors.green, +/// child: Material( +/// child: SwitchListTile( +/// tileColor: Colors.red, +/// title: const Text('SwitchListTile with red background'), +/// value: true, +/// onChanged:(bool? value) { }, +/// ), +/// ), +/// ) +/// ``` +/// {@end-tool} +/// +/// ## Performance considerations when wrapping [SwitchListTile] with [Material] +/// +/// Wrapping a large number of [SwitchListTile]s individually with [Material]s +/// is expensive. Consider only wrapping the [SwitchListTile]s that require it +/// or include a common [Material] ancestor where possible. +/// /// To show the [SwitchListTile] as disabled, pass null as the [onChanged] /// callback. /// @@ -217,6 +245,7 @@ class SwitchListTile extends StatelessWidget { /// [StatefulWidget] using the [State.setState] method, so that the parent /// gets rebuilt; for example: /// + /// {@tool snippet} /// ```dart /// SwitchListTile( /// value: _isSelected, @@ -225,9 +254,10 @@ class SwitchListTile extends StatelessWidget { /// _isSelected = newValue; /// }); /// }, - /// title: Text('Selection'), + /// title: const Text('Selection'), /// ) /// ``` + /// {@end-tool} final ValueChanged? onChanged; /// The color to use when this switch is on.