diff --git a/examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.0.dart b/examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.0.dart index fcb4244be09c..01152cde3038 100644 --- a/examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.0.dart +++ b/examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.0.dart @@ -7,46 +7,43 @@ import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart' show timeDilation; -void main() => runApp(const MyApp()); +void main() => runApp(const CheckboxListTileApp()); -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - static const String _title = 'Flutter Code Sample'; +class CheckboxListTileApp extends StatelessWidget { + const CheckboxListTileApp({super.key}); @override Widget build(BuildContext context) { - return MaterialApp( - title: _title, - home: Scaffold( - appBar: AppBar(title: const Text(_title)), - body: const Center( - child: MyStatefulWidget(), - ), - ), + return const MaterialApp( + home: CheckboxListTileExample(), ); } } -class MyStatefulWidget extends StatefulWidget { - const MyStatefulWidget({super.key}); +class CheckboxListTileExample extends StatefulWidget { + const CheckboxListTileExample({super.key}); @override - State createState() => _MyStatefulWidgetState(); + State createState() => _CheckboxListTileExampleState(); } -class _MyStatefulWidgetState extends State { +class _CheckboxListTileExampleState extends State { @override Widget build(BuildContext context) { - return CheckboxListTile( - title: const Text('Animate Slowly'), - value: timeDilation != 1.0, - onChanged: (bool? value) { - setState(() { - timeDilation = value! ? 10.0 : 1.0; - }); - }, - secondary: const Icon(Icons.hourglass_empty), + return Scaffold( + appBar: AppBar(title: const Text('CheckboxListTile Sample')), + body: Center( + child: CheckboxListTile( + title: const Text('Animate Slowly'), + value: timeDilation != 1.0, + onChanged: (bool? value) { + setState(() { + timeDilation = value! ? 10.0 : 1.0; + }); + }, + secondary: const Icon(Icons.hourglass_empty), + ), + ), ); } } diff --git a/examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.1.dart b/examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.1.dart index 61620bf38abb..de5bd6fb0dd1 100644 --- a/examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.1.dart +++ b/examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.1.dart @@ -4,99 +4,76 @@ // Flutter code sample for [CheckboxListTile]. -import 'package:flutter/gestures.dart'; - import 'package:flutter/material.dart'; -void main() => runApp(const MyApp()); - -class MyApp extends StatelessWidget { - const MyApp({super.key}); +void main() => runApp(const CheckboxListTileApp()); - static const String _title = 'Flutter Code Sample'; +class CheckboxListTileApp extends StatelessWidget { + const CheckboxListTileApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( - title: _title, - home: Scaffold( - appBar: AppBar(title: const Text(_title)), - body: const Center( - child: MyStatefulWidget(), - ), - ), + theme: ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true), + home: const CheckboxListTileExample(), ); } } -class LinkedLabelCheckbox extends StatelessWidget { - const LinkedLabelCheckbox({ - super.key, - required this.label, - required this.padding, - required this.value, - required this.onChanged, - }); +class CheckboxListTileExample extends StatefulWidget { + const CheckboxListTileExample({super.key}); - final String label; - final EdgeInsets padding; - final bool value; - final ValueChanged onChanged; + @override + State createState() => _CheckboxListTileExampleState(); +} + +class _CheckboxListTileExampleState extends State { + bool checkboxValue1 = true; + bool checkboxValue2 = true; + bool checkboxValue3 = true; @override Widget build(BuildContext context) { - return Padding( - padding: padding, - child: Row( + return Scaffold( + appBar: AppBar(title: const Text('CheckboxListTile Sample')), + body: Column( children: [ - Expanded( - child: RichText( - text: TextSpan( - text: label, - style: const TextStyle( - color: Colors.blueAccent, - decoration: TextDecoration.underline, - ), - recognizer: TapGestureRecognizer() - ..onTap = () { - debugPrint('Label has been tapped.'); - }, - ), - ), + CheckboxListTile( + value: checkboxValue1, + onChanged: (bool? value) { + setState(() { + checkboxValue1 = value!; + }); + }, + title: const Text('Headline'), + subtitle: const Text('Supporting text'), + ), + const Divider(height: 0), + CheckboxListTile( + value: checkboxValue2, + onChanged: (bool? value) { + setState(() { + checkboxValue2 = value!; + }); + }, + title: const Text('Headline'), + subtitle: const Text('Longer supporting text to demonstrate how the text wraps and the checkbox is centered vertically with the text.'), ), - Checkbox( - value: value, - onChanged: (bool? newValue) { - onChanged(newValue!); - }, + const Divider(height: 0), + CheckboxListTile( + value: checkboxValue3, + onChanged: (bool? value) { + setState(() { + checkboxValue3 = value!; + }); + }, + title: const Text('Headline'), + subtitle: const Text("Longer supporting text to demonstrate how the text wraps and how setting 'CheckboxListTile.isThreeLine = true' aligns the checkbox to the top vertically with the text."), + isThreeLine: true, ), + const Divider(height: 0), ], ), ); } } - -class MyStatefulWidget extends StatefulWidget { - const MyStatefulWidget({super.key}); - - @override - State createState() => _MyStatefulWidgetState(); -} - -class _MyStatefulWidgetState extends State { - bool _isSelected = false; - - @override - Widget build(BuildContext context) { - return LinkedLabelCheckbox( - label: 'Linked, tappable label text', - padding: const EdgeInsets.symmetric(horizontal: 20.0), - value: _isSelected, - onChanged: (bool newValue) { - setState(() { - _isSelected = newValue; - }); - }, - ); - } -} diff --git a/examples/api/lib/material/checkbox_list_tile/custom_labeled_checkbox.0.dart b/examples/api/lib/material/checkbox_list_tile/custom_labeled_checkbox.0.dart new file mode 100644 index 000000000000..fc5b0d3907ae --- /dev/null +++ b/examples/api/lib/material/checkbox_list_tile/custom_labeled_checkbox.0.dart @@ -0,0 +1,99 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flutter code sample for custom labeled checkbox. + +import 'package:flutter/gestures.dart'; + +import 'package:flutter/material.dart'; + +void main() => runApp(const LabeledCheckBoxApp()); + +class LabeledCheckBoxApp extends StatelessWidget { + const LabeledCheckBoxApp({super.key}); + + @override + Widget build(BuildContext context) { + return const MaterialApp( + home: LabeledCheckBoxExample(), + ); + } +} + +class LinkedLabelCheckbox extends StatelessWidget { + const LinkedLabelCheckbox({ + super.key, + required this.label, + required this.padding, + required this.value, + required this.onChanged, + }); + + final String label; + final EdgeInsets padding; + final bool value; + final ValueChanged onChanged; + + @override + Widget build(BuildContext context) { + return Padding( + padding: padding, + child: Row( + children: [ + Expanded( + child: RichText( + text: TextSpan( + text: label, + style: const TextStyle( + color: Colors.blueAccent, + decoration: TextDecoration.underline, + ), + recognizer: TapGestureRecognizer() + ..onTap = () { + debugPrint('Label has been tapped.'); + }, + ), + ), + ), + Checkbox( + value: value, + onChanged: (bool? newValue) { + onChanged(newValue!); + }, + ), + ], + ), + ); + } +} + +class LabeledCheckBoxExample extends StatefulWidget { + const LabeledCheckBoxExample({super.key}); + + @override + State createState() => _LabeledCheckBoxExampleState(); +} + +class _LabeledCheckBoxExampleState extends State { + bool _isSelected = false; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Custom Labeled Checkbox Sample')), + body: Center( + child: LinkedLabelCheckbox( + label: 'Linked, tappable label text', + padding: const EdgeInsets.symmetric(horizontal: 20.0), + value: _isSelected, + onChanged: (bool newValue) { + setState(() { + _isSelected = newValue; + }); + }, + ), + ), + ); + } +} diff --git a/examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.2.dart b/examples/api/lib/material/checkbox_list_tile/custom_labeled_checkbox.1.dart similarity index 56% rename from examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.2.dart rename to examples/api/lib/material/checkbox_list_tile/custom_labeled_checkbox.1.dart index a7b0a17994a9..245616622073 100644 --- a/examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.2.dart +++ b/examples/api/lib/material/checkbox_list_tile/custom_labeled_checkbox.1.dart @@ -2,27 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flutter code sample for [CheckboxListTile]. +// Flutter code sample for custom labeled checkbox. import 'package:flutter/material.dart'; -void main() => runApp(const MyApp()); +void main() => runApp(const LabeledCheckBoxApp()); -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - static const String _title = 'Flutter Code Sample'; +class LabeledCheckBoxApp extends StatelessWidget { + const LabeledCheckBoxApp({super.key}); @override Widget build(BuildContext context) { - return MaterialApp( - title: _title, - home: Scaffold( - appBar: AppBar(title: const Text(_title)), - body: const Center( - child: MyStatefulWidget(), - ), - ), + return const MaterialApp( + home: LabeledCheckBoxExample(), ); } } @@ -65,27 +57,32 @@ class LabeledCheckbox extends StatelessWidget { } } -class MyStatefulWidget extends StatefulWidget { - const MyStatefulWidget({super.key}); +class LabeledCheckBoxExample extends StatefulWidget { + const LabeledCheckBoxExample({super.key}); @override - State createState() => _MyStatefulWidgetState(); + State createState() => _LabeledCheckBoxExampleState(); } -class _MyStatefulWidgetState extends State { +class _LabeledCheckBoxExampleState extends State { bool _isSelected = false; @override Widget build(BuildContext context) { - return LabeledCheckbox( - label: 'This is the label text', - padding: const EdgeInsets.symmetric(horizontal: 20.0), - value: _isSelected, - onChanged: (bool newValue) { - setState(() { - _isSelected = newValue; - }); - }, + return Scaffold( + appBar: AppBar(title: const Text('Custom Labeled Checkbox Sample')), + body: Center( + child: LabeledCheckbox( + label: 'This is the label text', + padding: const EdgeInsets.symmetric(horizontal: 20.0), + value: _isSelected, + onChanged: (bool newValue) { + setState(() { + _isSelected = newValue; + }); + }, + ), + ), ); } } diff --git a/examples/api/lib/material/list_tile/list_tile.2.dart b/examples/api/lib/material/list_tile/list_tile.2.dart index 9b8d36e3bfe8..3a37177c8066 100644 --- a/examples/api/lib/material/list_tile/list_tile.2.dart +++ b/examples/api/lib/material/list_tile/list_tile.2.dart @@ -27,7 +27,7 @@ class ListTileExample extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('ListTile Sample')), - body: Column( + body: ListView( children: const [ ListTile( leading: CircleAvatar( @@ -37,7 +37,7 @@ class ListTileExample extends StatelessWidget { subtitle: Text('Supporting text'), trailing: Icon(Icons.favorite_rounded), ), - Divider(), + Divider(height: 0), ListTile( leading: CircleAvatar( child: Text('B') @@ -46,7 +46,7 @@ class ListTileExample extends StatelessWidget { subtitle: Text('Longer supporting text to demonstrate how the text wraps and how the leading and trailing widgets are centered vertically with the text.'), trailing: Icon(Icons.favorite_rounded), ), - Divider(), + Divider(height: 0), ListTile( leading: CircleAvatar( child: Text('C') @@ -56,7 +56,7 @@ class ListTileExample extends StatelessWidget { trailing: Icon(Icons.favorite_rounded), isThreeLine: true, ), - Divider(), + Divider(height: 0), ], ), ); diff --git a/examples/api/lib/material/list_tile/list_tile.3.dart b/examples/api/lib/material/list_tile/list_tile.3.dart index 91a437870de2..6ec41c2da5c4 100644 --- a/examples/api/lib/material/list_tile/list_tile.3.dart +++ b/examples/api/lib/material/list_tile/list_tile.3.dart @@ -35,54 +35,51 @@ class _ListTileExampleState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('ListTile Sample')), - body: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ListTile( - enabled: _enabled, - selected: _selected, - onTap: () { + body: Center( + child: ListTile( + enabled: _enabled, + selected: _selected, + onTap: () { + setState(() { + // This is called when the user toggles the switch. + _selected = !_selected; + }); + }, + // This sets text color and icon color to red when list tile is disabled and + // green when list tile is selected, otherwise sets it to black. + iconColor: MaterialStateColor.resolveWith((Set states) { + if (states.contains(MaterialState.disabled)) { + return Colors.red; + } + if (states.contains(MaterialState.selected)) { + return Colors.green; + } + return Colors.black; + }), + // This sets text color and icon color to red when list tile is disabled and + // green when list tile is selected, otherwise sets it to black. + textColor: MaterialStateColor.resolveWith((Set states) { + if (states.contains(MaterialState.disabled)) { + return Colors.red; + } + if (states.contains(MaterialState.selected)) { + return Colors.green; + } + return Colors.black; + }), + leading: const Icon(Icons.person), + title: const Text('Headline'), + subtitle: Text('Enabled: $_enabled, Selected: $_selected'), + trailing: Switch( + onChanged: (bool? value) { + // This is called when the user toggles the switch. setState(() { - // This is called when the user toggles the switch. - _selected = !_selected; + _enabled = value!; }); }, - // This sets text color and icon color to red when list tile is disabled and - // green when list tile is selected, otherwise sets it to black. - iconColor: MaterialStateColor.resolveWith((Set states) { - if (states.contains(MaterialState.disabled)) { - return Colors.red; - } - if (states.contains(MaterialState.selected)) { - return Colors.green; - } - return Colors.black; - }), - // This sets text color and icon color to red when list tile is disabled and - // green when list tile is selected, otherwise sets it to black. - textColor: MaterialStateColor.resolveWith((Set states) { - if (states.contains(MaterialState.disabled)) { - return Colors.red; - } - if (states.contains(MaterialState.selected)) { - return Colors.green; - } - return Colors.black; - }), - leading: const Icon(Icons.person), - title: const Text('Headline'), - subtitle: Text('Enabled: $_enabled, Selected: $_selected'), - trailing: Switch( - onChanged: (bool? value) { - // This is called when the user toggles the switch. - setState(() { - _enabled = value!; - }); - }, - value: _enabled, - ), + value: _enabled, ), - ], + ), ), ); } diff --git a/examples/api/test/material/checkbox_list_tile/checkbox_list_tile.0_test.dart b/examples/api/test/material/checkbox_list_tile/checkbox_list_tile.0_test.dart new file mode 100644 index 000000000000..bd65306d8a0b --- /dev/null +++ b/examples/api/test/material/checkbox_list_tile/checkbox_list_tile.0_test.dart @@ -0,0 +1,32 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:flutter_api_samples/material/checkbox_list_tile/checkbox_list_tile.0.dart' as example; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('CheckboxListTile can be checked', (WidgetTester tester) async { + await tester.pumpWidget( + const example.CheckboxListTileApp(), + ); + + CheckboxListTile checkboxListTile = tester.widget(find.byType(CheckboxListTile)); + expect(checkboxListTile.value, isFalse); + + await tester.tap(find.byType(CheckboxListTile)); + await tester.pump(); + timeDilation = 1.0; + + checkboxListTile = tester.widget(find.byType(CheckboxListTile)); + expect(checkboxListTile.value, isTrue); + + await tester.tap(find.byType(CheckboxListTile)); + await tester.pump(); + + checkboxListTile = tester.widget(find.byType(CheckboxListTile)); + expect(checkboxListTile.value, isFalse); + }); +} diff --git a/examples/api/test/material/checkbox_list_tile/checkbox_list_tile.1_test.dart b/examples/api/test/material/checkbox_list_tile/checkbox_list_tile.1_test.dart new file mode 100644 index 000000000000..bcc747f63d71 --- /dev/null +++ b/examples/api/test/material/checkbox_list_tile/checkbox_list_tile.1_test.dart @@ -0,0 +1,75 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_api_samples/material/checkbox_list_tile/checkbox_list_tile.1.dart' as example; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('Checkbox aligns appropriately', (WidgetTester tester) async { + await tester.pumpWidget( + const example.CheckboxListTileApp(), + ); + + expect(find.byType(CheckboxListTile), findsNWidgets(3)); + + Offset tileTopLeft = tester.getTopLeft(find.byType(CheckboxListTile).at(0)); + Offset checkboxTopLeft = tester.getTopLeft(find.byType(Checkbox).at(0)); + + // The checkbox is centered vertically with the text. + expect(checkboxTopLeft - tileTopLeft, const Offset(736.0, 16.0)); + + tileTopLeft = tester.getTopLeft(find.byType(CheckboxListTile).at(1)); + checkboxTopLeft = tester.getTopLeft(find.byType(Checkbox).at(1)); + + // The checkbox is centered vertically with the text. + expect(checkboxTopLeft - tileTopLeft, const Offset(736.0, 30.0)); + + tileTopLeft = tester.getTopLeft(find.byType(CheckboxListTile).at(2)); + checkboxTopLeft = tester.getTopLeft(find.byType(Checkbox).at(2)); + + // The checkbox is aligned to the top vertically with the text. + expect(checkboxTopLeft - tileTopLeft, const Offset(736.0, 8.0)); + }); + + testWidgets('Checkboxes can be checked', (WidgetTester tester) async { + await tester.pumpWidget( + const example.CheckboxListTileApp(), + ); + + expect(find.byType(CheckboxListTile), findsNWidgets(3)); + + // All checkboxes are checked. + expect(tester.widget(find.byType(Checkbox).at(0)).value, isTrue); + expect(tester.widget(find.byType(Checkbox).at(1)).value, isTrue); + expect(tester.widget(find.byType(Checkbox).at(2)).value, isTrue); + + // Tap the first checkbox. + await tester.tap(find.byType(Checkbox).at(0)); + await tester.pumpAndSettle(); + + // The first checkbox is unchecked. + expect(tester.widget(find.byType(Checkbox).at(0)).value, isFalse); + expect(tester.widget(find.byType(Checkbox).at(1)).value, isTrue); + expect(tester.widget(find.byType(Checkbox).at(2)).value, isTrue); + + // Tap the second checkbox. + await tester.tap(find.byType(Checkbox).at(1)); + await tester.pumpAndSettle(); + + // The first and second checkboxes are unchecked. + expect(tester.widget(find.byType(Checkbox).at(0)).value, isFalse); + expect(tester.widget(find.byType(Checkbox).at(1)).value, isFalse); + expect(tester.widget(find.byType(Checkbox).at(2)).value, isTrue); + + // Tap the third checkbox. + await tester.tap(find.byType(Checkbox).at(2)); + await tester.pumpAndSettle(); + + // All checkboxes are unchecked. + expect(tester.widget(find.byType(Checkbox).at(0)).value, isFalse); + expect(tester.widget(find.byType(Checkbox).at(1)).value, isFalse); + expect(tester.widget(find.byType(Checkbox).at(2)).value, isFalse); + }); +} diff --git a/examples/api/test/material/checkbox_list_tile/custom_labeled_checkbox.0_test.dart b/examples/api/test/material/checkbox_list_tile/custom_labeled_checkbox.0_test.dart new file mode 100644 index 000000000000..a07bcd25b152 --- /dev/null +++ b/examples/api/test/material/checkbox_list_tile/custom_labeled_checkbox.0_test.dart @@ -0,0 +1,31 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_api_samples/material/checkbox_list_tile/custom_labeled_checkbox.0.dart' as example; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('LinkedLabelCheckbox contains RichText and Checkbox', (WidgetTester tester) async { + await tester.pumpWidget( + const example.LabeledCheckBoxApp(), + ); + + // Label text is in a RichText widget with the correct text. + final RichText richText = tester.widget(find.byType(RichText).first); + expect(richText.text.toPlainText(), 'Linked, tappable label text'); + + // Checkbox is initially unchecked. + Checkbox checkbox = tester.widget(find.byType(Checkbox)); + expect(checkbox.value, isFalse); + + // Tap the checkbox to check it. + await tester.tap(find.byType(Checkbox)); + await tester.pumpAndSettle(); + + // Checkbox is now checked. + checkbox = tester.widget(find.byType(Checkbox)); + expect(checkbox.value, isTrue); + }); +} diff --git a/examples/api/test/material/checkbox_list_tile/custom_labeled_checkbox.1_test.dart b/examples/api/test/material/checkbox_list_tile/custom_labeled_checkbox.1_test.dart new file mode 100644 index 000000000000..e2498f879acc --- /dev/null +++ b/examples/api/test/material/checkbox_list_tile/custom_labeled_checkbox.1_test.dart @@ -0,0 +1,27 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:flutter_api_samples/material/checkbox_list_tile/custom_labeled_checkbox.1.dart' as example; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('Tapping LabeledCheckbox toggles the checkbox', (WidgetTester tester) async { + await tester.pumpWidget( + const example.LabeledCheckBoxApp(), + ); + + // Checkbox is initially unchecked. + Checkbox checkbox = tester.widget(find.byType(Checkbox)); + expect(checkbox.value, isFalse); + + // Tap the LabeledCheckBoxApp to toggle the checkbox. + await tester.tap(find.byType(example.LabeledCheckbox)); + await tester.pumpAndSettle(); + + // Checkbox is now checked. + checkbox = tester.widget(find.byType(Checkbox)); + expect(checkbox.value, isTrue); + }); +} diff --git a/packages/flutter/lib/src/material/checkbox_list_tile.dart b/packages/flutter/lib/src/material/checkbox_list_tile.dart index 9334e3421d7b..063a7e4ffc12 100644 --- a/packages/flutter/lib/src/material/checkbox_list_tile.dart +++ b/packages/flutter/lib/src/material/checkbox_list_tile.dart @@ -85,6 +85,13 @@ import 'theme_data.dart'; /// ** See code in examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.0.dart ** /// {@end-tool} /// +/// {@tool dartpad} +/// This sample shows the creation of a [CheckboxListTile] using [ThemeData.useMaterial3] flag, +/// as described in: https://m3.material.io/components/lists/overview. +/// +/// ** See code in examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.1.dart ** +/// {@end-tool} +/// /// ## Semantics in CheckboxListTile /// /// Since the entirety of the CheckboxListTile is interactive, it should represent @@ -109,7 +116,7 @@ import 'theme_data.dart'; /// LinkedLabelCheckbox, that includes an interactive [RichText] widget that /// handles tap gestures. /// -/// ** See code in examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.1.dart ** +/// ** See code in examples/api/lib/material/checkbox_list_tile/custom_labeled_checkbox.0.dart ** /// {@end-tool} /// /// ## CheckboxListTile isn't exactly what I want @@ -125,7 +132,7 @@ import 'theme_data.dart'; /// Here is an example of a custom LabeledCheckbox widget, but you can easily /// make your own configurable widget. /// -/// ** See code in examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.2.dart ** +/// ** See code in examples/api/lib/material/checkbox_list_tile/custom_labeled_checkbox.1.dart ** /// {@end-tool} /// /// See also: diff --git a/packages/flutter/lib/src/material/list_tile.dart b/packages/flutter/lib/src/material/list_tile.dart index 9a9044589053..ce3bf51cede8 100644 --- a/packages/flutter/lib/src/material/list_tile.dart +++ b/packages/flutter/lib/src/material/list_tile.dart @@ -146,11 +146,19 @@ enum ListTileControlAffinity { /// ** See code in examples/api/lib/material/list_tile/list_tile.2.dart ** /// {@end-tool} /// +/// {@tool dartpad} +/// This sample shows [ListTile]'s [textColor] and [iconColor] can use +/// [MaterialStateColor] color to change the color of the text and icon +/// when the [ListTile] is enabled, selected, or disabled. +/// +/// ** See code in examples/api/lib/material/list_tile/list_tile.3.dart ** +/// {@end-tool} +/// +/// {@tool snippet} /// To use a [ListTile] within a [Row], it needs to be wrapped in an /// [Expanded] widget. [ListTile] requires fixed width constraints, /// whereas a [Row] does not constrain its children. /// -/// {@tool snippet} /// ```dart /// Row( /// children: const [