Unverified Commit 3e71e0ca authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Updated `ListTile` documentation, add Material 3 example and other `ListTile`...

Updated `ListTile` documentation, add Material 3 example and other `ListTile` examples fixes. (#118705)
parent d53cc4a1
......@@ -2,25 +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 [ListTile].
// Flutter code sample for custom list items.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
void main() => runApp(const CustomListItemApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
class CustomListItemApp extends StatelessWidget {
const CustomListItemApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatelessWidget(),
),
return const MaterialApp(
home: CustomListItemExample(),
);
}
}
......@@ -109,32 +103,35 @@ class _VideoDescription extends StatelessWidget {
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({super.key});
class CustomListItemExample extends StatelessWidget {
const CustomListItemExample({super.key});
@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.all(8.0),
itemExtent: 106.0,
children: <CustomListItem>[
CustomListItem(
user: 'Flutter',
viewCount: 999000,
thumbnail: Container(
decoration: const BoxDecoration(color: Colors.blue),
return Scaffold(
appBar: AppBar(title: const Text('Custom List Item Sample')),
body: ListView(
padding: const EdgeInsets.all(8.0),
itemExtent: 106.0,
children: <CustomListItem>[
CustomListItem(
user: 'Flutter',
viewCount: 999000,
thumbnail: Container(
decoration: const BoxDecoration(color: Colors.blue),
),
title: 'The Flutter YouTube Channel',
),
title: 'The Flutter YouTube Channel',
),
CustomListItem(
user: 'Dash',
viewCount: 884000,
thumbnail: Container(
decoration: const BoxDecoration(color: Colors.yellow),
CustomListItem(
user: 'Dash',
viewCount: 884000,
thumbnail: Container(
decoration: const BoxDecoration(color: Colors.yellow),
),
title: 'Announcing Flutter 1.0',
),
title: 'Announcing Flutter 1.0',
),
],
],
),
);
}
}
......@@ -2,25 +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 [ListTile].
// Flutter code sample for custom list items.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
void main() => runApp(const CustomListItemApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
class CustomListItemApp extends StatelessWidget {
const CustomListItemApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatelessWidget(),
),
return const MaterialApp(
home: CustomListItemExample(),
);
}
}
......@@ -147,36 +141,39 @@ class CustomListItemTwo extends StatelessWidget {
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({super.key});
class CustomListItemExample extends StatelessWidget {
const CustomListItemExample({super.key});
@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.all(10.0),
children: <Widget>[
CustomListItemTwo(
thumbnail: Container(
decoration: const BoxDecoration(color: Colors.pink),
return Scaffold(
appBar: AppBar(title: const Text('Custom List Item Sample')),
body: ListView(
padding: const EdgeInsets.all(10.0),
children: <Widget>[
CustomListItemTwo(
thumbnail: Container(
decoration: const BoxDecoration(color: Colors.pink),
),
title: 'Flutter 1.0 Launch',
subtitle: 'Flutter continues to improve and expand its horizons. '
'This text should max out at two lines and clip',
author: 'Dash',
publishDate: 'Dec 28',
readDuration: '5 mins',
),
title: 'Flutter 1.0 Launch',
subtitle: 'Flutter continues to improve and expand its horizons. '
'This text should max out at two lines and clip',
author: 'Dash',
publishDate: 'Dec 28',
readDuration: '5 mins',
),
CustomListItemTwo(
thumbnail: Container(
decoration: const BoxDecoration(color: Colors.blue),
CustomListItemTwo(
thumbnail: Container(
decoration: const BoxDecoration(color: Colors.blue),
),
title: 'Flutter 1.2 Release - Continual updates to the framework',
subtitle: 'Flutter once again improves and makes updates.',
author: 'Flutter',
publishDate: 'Feb 26',
readDuration: '12 mins',
),
title: 'Flutter 1.2 Release - Continual updates to the framework',
subtitle: 'Flutter once again improves and makes updates.',
author: 'Flutter',
publishDate: 'Feb 26',
readDuration: '12 mins',
),
],
],
),
);
}
}
......@@ -19,10 +19,7 @@ class ListTileApp extends StatelessWidget {
textColor: Colors.white,
)
),
home: Scaffold(
appBar: AppBar(title: const Text('ListTile Samples')),
body: const LisTileExample(),
),
home: const LisTileExample(),
);
}
}
......@@ -73,77 +70,80 @@ class _LisTileExampleState extends State<LisTileExample> with TickerProviderStat
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Hero(
tag: 'ListTile-Hero',
// Wrap the ListTile in a Material widget so the ListTile has someplace
// to draw the animated colors during the hero transition.
child: Material(
child: ListTile(
title: const Text('ListTile with Hero'),
subtitle: const Text('Tap here for Hero transition'),
tileColor: Colors.cyan,
onTap: () {
Navigator.push(context, MaterialPageRoute<Widget>(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('ListTile Hero')),
body: Center(
child: Hero(
tag: 'ListTile-Hero',
child: Material(
child: ListTile(
title: const Text('ListTile with Hero'),
subtitle: const Text('Tap here to go back'),
tileColor: Colors.blue[700],
onTap: () {
Navigator.pop(context);
},
return Scaffold(
appBar: AppBar(title: const Text('ListTile Samples')),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Hero(
tag: 'ListTile-Hero',
// Wrap the ListTile in a Material widget so the ListTile has someplace
// to draw the animated colors during the hero transition.
child: Material(
child: ListTile(
title: const Text('ListTile with Hero'),
subtitle: const Text('Tap here for Hero transition'),
tileColor: Colors.cyan,
onTap: () {
Navigator.push(context, MaterialPageRoute<Widget>(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('ListTile Hero')),
body: Center(
child: Hero(
tag: 'ListTile-Hero',
child: Material(
child: ListTile(
title: const Text('ListTile with Hero'),
subtitle: const Text('Tap here to go back'),
tileColor: Colors.blue[700],
onTap: () {
Navigator.pop(context);
},
),
),
),
),
),
);
}),
);
},
);
}),
);
},
),
),
),
),
FadeTransition(
opacity: _fadeAnimation,
// Wrap the ListTile in a Material widget so the ListTile has someplace
// to draw the animated colors during the fade transition.
child: const Material(
child: ListTile(
title: Text('ListTile with FadeTransition'),
selectedTileColor: Colors.green,
selectedColor: Colors.white,
selected: true,
FadeTransition(
opacity: _fadeAnimation,
// Wrap the ListTile in a Material widget so the ListTile has someplace
// to draw the animated colors during the fade transition.
child: const Material(
child: ListTile(
title: Text('ListTile with FadeTransition'),
selectedTileColor: Colors.green,
selectedColor: Colors.white,
selected: true,
),
),
),
),
SizedBox(
height: 100,
child: Center(
child: SizeTransition(
sizeFactor: _sizeAnimation,
axisAlignment: -1.0,
// Wrap the ListTile in a Material widget so the ListTile has someplace
// to draw the animated colors during the size transition.
child: const Material(
child: ListTile(
title: Text('ListTile with SizeTransition'),
tileColor: Colors.red,
minVerticalPadding: 25.0,
SizedBox(
height: 100,
child: Center(
child: SizeTransition(
sizeFactor: _sizeAnimation,
axisAlignment: -1.0,
// Wrap the ListTile in a Material widget so the ListTile has someplace
// to draw the animated colors during the size transition.
child: const Material(
child: ListTile(
title: Text('ListTile with SizeTransition'),
tileColor: Colors.red,
minVerticalPadding: 25.0,
),
),
),
),
),
),
],
],
),
);
}
}
......@@ -13,11 +13,8 @@ class ListTileApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('ListTile Sample')),
body: const LisTileExample(),
),
return const MaterialApp(
home: LisTileExample(),
);
}
}
......@@ -27,54 +24,57 @@ class LisTileExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: const <Widget>[
Card(child: ListTile(title: Text('One-line ListTile'))),
Card(
child: ListTile(
leading: FlutterLogo(),
title: Text('One-line with leading widget'),
return Scaffold(
appBar: AppBar(title: const Text('ListTile Sample')),
body: ListView(
children: const <Widget>[
Card(child: ListTile(title: Text('One-line ListTile'))),
Card(
child: ListTile(
leading: FlutterLogo(),
title: Text('One-line with leading widget'),
),
),
),
Card(
child: ListTile(
title: Text('One-line with trailing widget'),
trailing: Icon(Icons.more_vert),
Card(
child: ListTile(
title: Text('One-line with trailing widget'),
trailing: Icon(Icons.more_vert),
),
),
),
Card(
child: ListTile(
leading: FlutterLogo(),
title: Text('One-line with both widgets'),
trailing: Icon(Icons.more_vert),
Card(
child: ListTile(
leading: FlutterLogo(),
title: Text('One-line with both widgets'),
trailing: Icon(Icons.more_vert),
),
),
),
Card(
child: ListTile(
title: Text('One-line dense ListTile'),
dense: true,
Card(
child: ListTile(
title: Text('One-line dense ListTile'),
dense: true,
),
),
),
Card(
child: ListTile(
leading: FlutterLogo(size: 56.0),
title: Text('Two-line ListTile'),
subtitle: Text('Here is a second line'),
trailing: Icon(Icons.more_vert),
Card(
child: ListTile(
leading: FlutterLogo(size: 56.0),
title: Text('Two-line ListTile'),
subtitle: Text('Here is a second line'),
trailing: Icon(Icons.more_vert),
),
),
),
Card(
child: ListTile(
leading: FlutterLogo(size: 72.0),
title: Text('Three-line ListTile'),
subtitle: Text(
'A sufficiently long subtitle warrants three lines.'
Card(
child: ListTile(
leading: FlutterLogo(size: 72.0),
title: Text('Three-line ListTile'),
subtitle: Text(
'A sufficiently long subtitle warrants three lines.'
),
trailing: Icon(Icons.more_vert),
isThreeLine: true,
),
trailing: Icon(Icons.more_vert),
isThreeLine: true,
),
),
],
],
),
);
}
}
// 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 [ListTile].
import 'package:flutter/material.dart';
void main() => runApp(const ListTileApp());
class ListTileApp extends StatelessWidget {
const ListTileApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true),
home: const ListTileExample(),
);
}
}
class ListTileExample extends StatelessWidget {
const ListTileExample({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('ListTile Sample')),
body: Column(
children: const <Widget>[
ListTile(
leading: CircleAvatar(
child: Text('A')
),
title: Text('Headline'),
subtitle: Text('Supporting text'),
trailing: Icon(Icons.favorite_rounded),
),
Divider(),
ListTile(
leading: CircleAvatar(
child: Text('B')
),
title: Text('Headline'),
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(),
ListTile(
leading: CircleAvatar(
child: Text('C')
),
title: Text('Headline'),
subtitle: Text("Longer supporting text to demonstrate how the text wraps and how setting 'ListTile.isThreeLine = true' aligns leading and trailing widgets to the top vertically with the text."),
trailing: Icon(Icons.favorite_rounded),
isThreeLine: true,
),
Divider(),
],
),
);
}
}
// 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 [ListTile].
import 'package:flutter/material.dart';
void main() => runApp(const ListTileApp());
class ListTileApp extends StatelessWidget {
const ListTileApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true),
home: const ListTileExample(),
);
}
}
class ListTileExample extends StatefulWidget {
const ListTileExample({super.key});
@override
State<ListTileExample> createState() => _ListTileExampleState();
}
class _ListTileExampleState extends State<ListTileExample> {
bool _selected = false;
bool _enabled = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('ListTile Sample')),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
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<MaterialState> 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<MaterialState> 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,
),
),
],
),
);
}
}
......@@ -6,50 +6,46 @@
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
void main() => runApp(const ListTileApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
class ListTileApp extends StatelessWidget {
const ListTileApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatefulWidget(),
),
return const MaterialApp(
home: LisTileExample(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
class LisTileExample extends StatefulWidget {
const LisTileExample({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
State<LisTileExample> createState() => _LisTileExampleState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
class _LisTileExampleState extends State<LisTileExample> {
int _selectedIndex = 0;
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text('Item $index'),
selected: index == _selectedIndex,
onTap: () {
setState(() {
_selectedIndex = index;
});
},
);
},
return Scaffold(
appBar: AppBar(title: const Text('Custom List Item Sample')),
body: ListView.builder(
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text('Item $index'),
selected: index == _selectedIndex,
onTap: () {
setState(() {
_selectedIndex = index;
});
},
);
},
),
);
}
}
// 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/list_tile/custom_list_item.0.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Custom list item uses Expanded widgets for the layout', (WidgetTester tester) async {
await tester.pumpWidget(
const example.CustomListItemApp(),
);
// The Expanded widget is used to control the size of the thumbnail.
Expanded thumbnailExpanded = tester.widget(find.ancestor(
of: find.byType(Container).first,
matching: find.byType(Expanded),
));
expect(thumbnailExpanded.flex, 2);
// The Expanded widget is used to control the size of the text.
Expanded textExpanded = tester.widget(find.ancestor(
of: find.text('The Flutter YouTube Channel'),
matching: find.byType(Expanded),
));
expect(textExpanded.flex, 3);
// The Expanded widget is used to control the size of the thumbnail.
thumbnailExpanded = tester.widget(find.ancestor(
of: find.byType(Container).last,
matching: find.byType(Expanded),
));
expect(thumbnailExpanded.flex, 2);
// The Expanded widget is used to control the size of the text.
textExpanded = tester.widget(find.ancestor(
of: find.text('Announcing Flutter 1.0'),
matching: find.byType(Expanded),
));
expect(textExpanded.flex, 3);
});
}
// 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/list_tile/custom_list_item.1.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Custom list item uses AspectRatio and Expanded widgets for the layout', (WidgetTester tester) async {
await tester.pumpWidget(
const example.CustomListItemApp(),
);
// The AspectRatio widget is used to constrain the size of the thumbnail.
AspectRatio thumbnailAspectRatio = tester.widget(find.ancestor(
of: find.byType(Container).first,
matching: find.byType(AspectRatio),
));
expect(thumbnailAspectRatio.aspectRatio, 1.0);
// The Expanded widget is used to control the size of the text.
Expanded textExpanded = tester.widget(find.ancestor(
of: find.text('Flutter 1.0 Launch'),
matching: find.byType(Expanded).at(0),
));
expect(textExpanded.flex, 1);
// The AspectRatio widget is used to constrain the size of the thumbnail.
thumbnailAspectRatio = tester.widget(find.ancestor(
of: find.byType(Container).last,
matching: find.byType(AspectRatio),
));
expect(thumbnailAspectRatio.aspectRatio, 1.0);
// The Expanded widget is used to control the size of the text.
textExpanded = tester.widget(find.ancestor(
of: find.text('Flutter 1.2 Release - Continual updates to the framework'),
matching: find.byType(Expanded).at(3),
));
expect(textExpanded.flex, 1);
});
}
......@@ -21,8 +21,12 @@ void main() {
expect(find.text(heroTransitionText), findsOneWidget);
expect(find.text(goBackText), findsNothing);
// Tap on the ListTile widget to trigger the Hero transition.
await tester.tap(find.text(heroTransitionText));
await tester.pumpAndSettle();
// The Hero transition is triggered and tap to go back text is displayed.
expect(find.text(heroTransitionText), findsNothing);
expect(find.text(goBackText), findsOneWidget);
......
......@@ -16,6 +16,7 @@ void main() {
expect(find.byType(ListTile), findsNWidgets(totalTiles));
// The ListTile widget is wrapped in a Card widget.
for (int i = 0; i < totalTiles; i++) {
expect(
find.ancestor(
......
// 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/list_tile/list_tile.2.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('ListTile leading and trailing widgets are aligned appropriately', (WidgetTester tester) async {
await tester.pumpWidget(
const example.ListTileApp(),
);
expect(find.byType(ListTile), findsNWidgets(3));
Offset listTileTopLeft = tester.getTopLeft(find.byType(ListTile).at(0));
Offset leadingTopLeft = tester.getTopLeft(find.byType(CircleAvatar).at(0));
Offset trailingTopLeft = tester.getTopLeft(find.byType(Icon).at(0));
// The leading and trailing widgets are centered vertically with the text.
expect(leadingTopLeft - listTileTopLeft, const Offset(16.0, 16.0));
expect(trailingTopLeft - listTileTopLeft, const Offset(752.0, 24.0));
listTileTopLeft = tester.getTopLeft(find.byType(ListTile).at(1));
leadingTopLeft = tester.getTopLeft(find.byType(CircleAvatar).at(1));
trailingTopLeft = tester.getTopLeft(find.byType(Icon).at(1));
// The leading and trailing widgets are centered vertically with the text.
expect(leadingTopLeft - listTileTopLeft, const Offset(16.0, 30.0));
expect(trailingTopLeft - listTileTopLeft, const Offset(752.0, 38.0));
listTileTopLeft = tester.getTopLeft(find.byType(ListTile).at(2));
leadingTopLeft = tester.getTopLeft(find.byType(CircleAvatar).at(2));
trailingTopLeft = tester.getTopLeft(find.byType(Icon).at(2));
// The leading and trailing widgets are aligned to the top vertically with the text.
expect(leadingTopLeft - listTileTopLeft, const Offset(16.0, 8.0));
expect(trailingTopLeft - listTileTopLeft, const Offset(752.0, 8.0));
});
}
// 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/rendering.dart';
import 'package:flutter_api_samples/material/list_tile/list_tile.3.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('ListTile color properties respect Material state color', (WidgetTester tester) async {
await tester.pumpWidget(
const example.ListTileApp(),
);
ListTile listTile = tester.widget(find.byType(ListTile));
// Enabled list tile uses black color for icon and headline.
expect(listTile.enabled, true);
expect(listTile.selected, false);
RenderParagraph headline = _getTextRenderObject(tester, 'Headline');
expect(headline.text.style!.color, Colors.black);
RichText icon = tester.widget(find.byType(RichText).at(0));
expect(icon.text.style!.color, Colors.black);
// Tap list tile to select it.
await tester.tap(find.byType(ListTile));
await tester.pumpAndSettle();
// Selected list tile uses green color for icon and headline.
listTile = tester.widget(find.byType(ListTile));
expect(listTile.enabled, true);
expect(listTile.selected, true);
headline = _getTextRenderObject(tester, 'Headline');
expect(headline.text.style!.color, Colors.green);
icon = tester.widget(find.byType(RichText).at(0));
expect(icon.text.style!.color, Colors.green);
// Tap switch to disable list tile.
await tester.tap(find.byType(Switch));
await tester.pumpAndSettle();
// Disabled list tile uses red color for icon and headline.
listTile = tester.widget(find.byType(ListTile));
expect(listTile.enabled, false);
expect(listTile.selected, true);
headline = _getTextRenderObject(tester, 'Headline');
expect(headline.text.style!.color, Colors.red);
icon = tester.widget(find.byType(RichText).at(0));
expect(icon.text.style!.color, Colors.red);
});
}
RenderParagraph _getTextRenderObject(WidgetTester tester, String text) {
return tester.renderObject(find.descendant(
of: find.byType(ListTile),
matching: find.text(text),
));
}
// 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/list_tile/list_tile.selected.0.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('ListTile item can be selected', (WidgetTester tester) async {
await tester.pumpWidget(
const example.ListTileApp(),
);
expect(find.byType(ListTile), findsNWidgets(10));
// The first item is selected by default.
expect(tester.widget<ListTile>(find.byType(ListTile).at(0)).selected, true);
// Tap a list item to select it.
await tester.tap(find.byType(ListTile).at(5));
await tester.pump();
// The first item is no longer selected.
expect(tester.widget<ListTile>(find.byType(ListTile).at(0)).selected, false);
expect(tester.widget<ListTile>(find.byType(ListTile).at(5)).selected, true);
});
}
......@@ -139,12 +139,18 @@ enum ListTileControlAffinity {
/// ** See code in examples/api/lib/material/list_tile/list_tile.1.dart **
/// {@end-tool}
///
/// {@tool snippet}
/// {@tool dartpad}
/// This sample shows the creation of a [ListTile] using [ThemeData.useMaterial3] flag,
/// as described in: https://m3.material.io/components/lists/overview.
///
/// ** See code in examples/api/lib/material/list_tile/list_tile.2.dart **
/// {@end-tool}
///
/// 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 <Widget>[
......@@ -231,7 +237,7 @@ enum ListTileControlAffinity {
///
/// ![Custom list item a](https://flutter.github.io/assets-for-api-docs/assets/widgets/custom_list_item_a.png)
///
/// ** See code in examples/api/lib/material/list_tile/list_tile.4.dart **
/// ** See code in examples/api/lib/material/list_tile/custom_list_item.0.dart **
/// {@end-tool}
///
/// {@tool dartpad}
......@@ -241,7 +247,7 @@ enum ListTileControlAffinity {
///
/// ![Custom list item b](https://flutter.github.io/assets-for-api-docs/assets/widgets/custom_list_item_b.png)
///
/// ** See code in examples/api/lib/material/list_tile/list_tile.5.dart **
/// ** See code in examples/api/lib/material/list_tile/custom_list_item.1.dart **
/// {@end-tool}
///
/// See also:
......@@ -409,7 +415,16 @@ class ListTile extends StatelessWidget {
/// Defines the default color for [leading] and [trailing] icons.
///
/// If this property is null then [ListTileThemeData.iconColor] is used.
/// If this property is null and [selected] is false then [ListTileThemeData.iconColor]
/// is used. If that is also null and [ThemeData.useMaterial3] is true, [ColorScheme.onSurface]
/// is used, otherwise if [ThemeData.brightness] is [Brightness.light], [Colors.black54] is used,
/// and if [ThemeData.brightness] is [Brightness.dark], the value is null.
///
/// If this property is null and [selected] is true then [ListTileThemeData.selectedColor]
/// is used. If that is also null then [ColorScheme.primary] is used.
///
/// If this color is a [MaterialStateColor] it will be resolved against
/// [MaterialState.selected] and [MaterialState.disabled] states.
///
/// See also:
///
......@@ -417,10 +432,18 @@ class ListTile extends StatelessWidget {
/// [ListTileThemeData].
final Color? iconColor;
/// Defines the default color for the [title] and [subtitle].
/// Defines the text color for the [title], [subtitle], [leading], and [trailing].
///
/// If this property is null and [selected] is false then [ListTileThemeData.textColor]
/// is used. If that is also null then default text color is used for the [title], [subtitle]
/// [leading], and [trailing]. Except for [subtitle], if [ThemeData.useMaterial3] is false,
/// [TextTheme.bodySmall] is used.
///
/// If this property is null and [selected] is true then [ListTileThemeData.selectedColor]
/// is used. If that is also null then [ColorScheme.primary] is used.
///
/// If this property is null then [ListTileThemeData.textColor] is used. If that
/// is also null then [ColorScheme.primary] is used.
/// If this color is a [MaterialStateColor] it will be resolved against
/// [MaterialState.selected] and [MaterialState.disabled] states.
///
/// See also:
///
......@@ -541,8 +564,11 @@ class ListTile extends StatelessWidget {
/// {@template flutter.material.ListTile.tileColor}
/// Defines the background color of `ListTile` when [selected] is false.
///
/// When the value is null, the [tileColor] is set to [ListTileTheme.tileColor]
/// if it's not null and to [Colors.transparent] if it's null.
/// If this property is null and [selected] is false then [ListTileThemeData.tileColor]
/// is used. If that is also null and [selected] is true, [selectedTileColor] is used.
/// When that is also null, the [ListTileTheme.selectedTileColor] is used, otherwise
/// [Colors.transparent] is used.
///
/// {@endtemplate}
final Color? tileColor;
......
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