Unverified Commit bbca7ff6 authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Add Material 3 `SwitchListTile` example and update existing examples (#119714)

* Add Material 3 `SwitchListTile` example and update existing examples

* Update examples with `useMaterial3: true` and update example descriptions.

* add a `ColorScheme` colour
parent b8f5394a
......@@ -14,8 +14,9 @@ class CheckboxListTileApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: CheckboxListTileExample(),
return MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const CheckboxListTileExample(),
);
}
}
......
......@@ -14,7 +14,7 @@ class CheckboxListTileApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true),
theme: ThemeData(useMaterial3: true),
home: const CheckboxListTileExample(),
);
}
......@@ -44,7 +44,7 @@ class _CheckboxListTileExampleState extends State<CheckboxListTileExample> {
setState(() {
checkboxValue1 = value!;
});
},
},
title: const Text('Headline'),
subtitle: const Text('Supporting text'),
),
......@@ -55,7 +55,7 @@ class _CheckboxListTileExampleState extends State<CheckboxListTileExample> {
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.'),
),
......@@ -66,7 +66,7 @@ class _CheckboxListTileExampleState extends State<CheckboxListTileExample> {
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,
......
......@@ -8,15 +8,16 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() => runApp(const LabeledCheckBoxApp());
void main() => runApp(const LabeledCheckboxApp());
class LabeledCheckBoxApp extends StatelessWidget {
const LabeledCheckBoxApp({super.key});
class LabeledCheckboxApp extends StatelessWidget {
const LabeledCheckboxApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: LabeledCheckBoxExample(),
return MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const LabeledCheckboxExample(),
);
}
}
......@@ -68,14 +69,14 @@ class LinkedLabelCheckbox extends StatelessWidget {
}
}
class LabeledCheckBoxExample extends StatefulWidget {
const LabeledCheckBoxExample({super.key});
class LabeledCheckboxExample extends StatefulWidget {
const LabeledCheckboxExample({super.key});
@override
State<LabeledCheckBoxExample> createState() => _LabeledCheckBoxExampleState();
State<LabeledCheckboxExample> createState() => _LabeledCheckboxExampleState();
}
class _LabeledCheckBoxExampleState extends State<LabeledCheckBoxExample> {
class _LabeledCheckboxExampleState extends State<LabeledCheckboxExample> {
bool _isSelected = false;
@override
......
......@@ -6,15 +6,16 @@
import 'package:flutter/material.dart';
void main() => runApp(const LabeledCheckBoxApp());
void main() => runApp(const LabeledCheckboxApp());
class LabeledCheckBoxApp extends StatelessWidget {
const LabeledCheckBoxApp({super.key});
class LabeledCheckboxApp extends StatelessWidget {
const LabeledCheckboxApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: LabeledCheckBoxExample(),
return MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const LabeledCheckboxExample(),
);
}
}
......@@ -57,14 +58,14 @@ class LabeledCheckbox extends StatelessWidget {
}
}
class LabeledCheckBoxExample extends StatefulWidget {
const LabeledCheckBoxExample({super.key});
class LabeledCheckboxExample extends StatefulWidget {
const LabeledCheckboxExample({super.key});
@override
State<LabeledCheckBoxExample> createState() => _LabeledCheckBoxExampleState();
State<LabeledCheckboxExample> createState() => _LabeledCheckboxExampleState();
}
class _LabeledCheckBoxExampleState extends State<LabeledCheckBoxExample> {
class _LabeledCheckboxExampleState extends State<LabeledCheckboxExample> {
bool _isSelected = false;
@override
......
// 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 switch.
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() => runApp(const LabeledSwitchApp());
class LabeledSwitchApp extends StatelessWidget {
const LabeledSwitchApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(useMaterial3: true),
home: Scaffold(
appBar: AppBar(title: const Text('Custom Labeled Switch Sample')),
body: const Center(
child: LabeledSwitchExample(),
),
),
);
}
}
class LinkedLabelSwitch extends StatelessWidget {
const LinkedLabelSwitch({
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<bool> onChanged;
@override
Widget build(BuildContext context) {
return Padding(
padding: padding,
child: Row(
children: <Widget>[
Expanded(
child: RichText(
text: TextSpan(
text: label,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
decoration: TextDecoration.underline,
),
recognizer: TapGestureRecognizer()
..onTap = () {
debugPrint('Label has been tapped.');
},
),
),
),
Switch(
value: value,
onChanged: (bool newValue) {
onChanged(newValue);
},
),
],
),
);
}
}
class LabeledSwitchExample extends StatefulWidget {
const LabeledSwitchExample({super.key});
@override
State<LabeledSwitchExample> createState() => _LabeledSwitchExampleState();
}
class _LabeledSwitchExampleState extends State<LabeledSwitchExample> {
bool _isSelected = false;
@override
Widget build(BuildContext context) {
return LinkedLabelSwitch(
label: 'Linked, tappable label text',
padding: const EdgeInsets.symmetric(horizontal: 20.0),
value: _isSelected,
onChanged: (bool newValue) {
setState(() {
_isSelected = newValue;
});
},
);
}
}
......@@ -2,25 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flutter code sample for [SwitchListTile].
// Flutter code sample for custom labeled switch.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
void main() => runApp(const LabeledSwitchApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
class LabeledSwitchApp extends StatelessWidget {
const LabeledSwitchApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
theme: ThemeData(useMaterial3: true),
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
appBar: AppBar(title: const Text('Custom Labeled Switch Sample')),
body: const Center(
child: MyStatefulWidget(),
child: LabeledSwitchExample(),
),
),
);
......@@ -65,14 +63,14 @@ class LabeledSwitch extends StatelessWidget {
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
class LabeledSwitchExample extends StatefulWidget {
const LabeledSwitchExample({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
State<LabeledSwitchExample> createState() => _LabeledSwitchExampleState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
class _LabeledSwitchExampleState extends State<LabeledSwitchExample> {
bool _isSelected = false;
@override
......
......@@ -6,35 +6,33 @@
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
void main() => runApp(const SwitchListTileApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
class SwitchListTileApp extends StatelessWidget {
const SwitchListTileApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
theme: ThemeData(useMaterial3: true),
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
appBar: AppBar(title: const Text('SwitchListTile Sample')),
body: const Center(
child: MyStatefulWidget(),
child: SwitchListTileExample(),
),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
class SwitchListTileExample extends StatefulWidget {
const SwitchListTileExample({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
State<SwitchListTileExample> createState() => _SwitchListTileExampleState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
class _SwitchListTileExampleState extends State<SwitchListTileExample> {
bool _lights = false;
@override
......
......@@ -4,99 +4,77 @@
// Flutter code sample for [SwitchListTile].
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 SwitchListTileApp());
static const String _title = 'Flutter Code Sample';
class SwitchListTileApp extends StatelessWidget {
const SwitchListTileApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
theme: ThemeData(useMaterial3: true),
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const Center(
child: MyStatefulWidget(),
),
),
appBar: AppBar(title: const Text('SwitchListTile Sample')),
body: const SwitchListTileExample()),
);
}
}
class LinkedLabelSwitch extends StatelessWidget {
const LinkedLabelSwitch({
super.key,
required this.label,
required this.padding,
required this.value,
required this.onChanged,
});
class SwitchListTileExample extends StatefulWidget {
const SwitchListTileExample({super.key});
@override
State<SwitchListTileExample> createState() => _SwitchListTileExampleState();
}
final String label;
final EdgeInsets padding;
final bool value;
final ValueChanged<bool> onChanged;
class _SwitchListTileExampleState extends State<SwitchListTileExample> {
bool switchValue1 = true;
bool switchValue2 = true;
bool switchValue3 = true;
@override
Widget build(BuildContext context) {
return Padding(
padding: padding,
child: Row(
return Scaffold(
body: Column(
children: <Widget>[
Expanded(
child: RichText(
text: TextSpan(
text: label,
style: const TextStyle(
color: Colors.blueAccent,
decoration: TextDecoration.underline,
),
recognizer: TapGestureRecognizer()
..onTap = () {
debugPrint('Label has been tapped.');
},
),
),
SwitchListTile(
value: switchValue1,
onChanged: (bool? value) {
setState(() {
switchValue1 = value!;
});
},
title: const Text('Headline'),
subtitle: const Text('Supporting text'),
),
Switch(
value: value,
onChanged: (bool newValue) {
onChanged(newValue);
const Divider(height: 0),
SwitchListTile(
value: switchValue2,
onChanged: (bool? value) {
setState(() {
switchValue2 = value!;
});
},
title: const Text('Headline'),
subtitle: const Text('Longer supporting text to demonstrate how the text wraps and the switch is centered vertically with the text.'),
),
const Divider(height: 0),
SwitchListTile(
value: switchValue3,
onChanged: (bool? value) {
setState(() {
switchValue3 = value!;
});
},
title: const Text('Headline'),
subtitle: const Text("Longer supporting text to demonstrate how the text wraps and how setting 'SwitchListTile.isThreeLine = true' aligns the switch to the top vertically with the text."),
isThreeLine: true,
),
const Divider(height: 0),
],
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
bool _isSelected = false;
@override
Widget build(BuildContext context) {
return LinkedLabelSwitch(
label: 'Linked, tappable label text',
padding: const EdgeInsets.symmetric(horizontal: 20.0),
value: _isSelected,
onChanged: (bool newValue) {
setState(() {
_isSelected = newValue;
});
},
);
}
}
......@@ -9,7 +9,7 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('LinkedLabelCheckbox contains RichText and Checkbox', (WidgetTester tester) async {
await tester.pumpWidget(
const example.LabeledCheckBoxApp(),
const example.LabeledCheckboxApp(),
);
// Label text is in a RichText widget with the correct text.
......
......@@ -9,7 +9,7 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Tapping LabeledCheckbox toggles the checkbox', (WidgetTester tester) async {
await tester.pumpWidget(
const example.LabeledCheckBoxApp(),
const example.LabeledCheckboxApp(),
);
// Checkbox is initially unchecked.
......
// 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/switch_list_tile/custom_labeled_switch.0.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('LinkedLabelSwitch contains RichText and Switch', (WidgetTester tester) async {
await tester.pumpWidget(
const example.LabeledSwitchApp(),
);
// 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');
// Switch is initially off.
Switch switchWidget = tester.widget(find.byType(Switch));
expect(switchWidget.value, isFalse);
// Tap to toggle the switch.
await tester.tap(find.byType(Switch));
await tester.pumpAndSettle();
// Switch is now on.
switchWidget = tester.widget(find.byType(Switch));
expect(switchWidget.value, isTrue);
});
}
// 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/switch_list_tile/custom_labeled_switch.1.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Tapping LabeledSwitch toggles the switch', (WidgetTester tester) async {
await tester.pumpWidget(
const example.LabeledSwitchApp(),
);
// Switch is initially off.
Switch switchWidget = tester.widget(find.byType(Switch));
expect(switchWidget.value, isFalse);
// Tap to toggle the switch.
await tester.tap(find.byType(example.LabeledSwitch));
await tester.pumpAndSettle();
// Switch is now on.
switchWidget = tester.widget(find.byType(Switch));
expect(switchWidget.value, isTrue);
});
}
// 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/switch_list_tile/switch_list_tile.0.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('SwitchListTile can be toggled', (WidgetTester tester) async {
await tester.pumpWidget(
const example.SwitchListTileApp(),
);
expect(find.byType(SwitchListTile), findsOneWidget);
SwitchListTile switchListTile = tester.widget(find.byType(SwitchListTile));
expect(switchListTile.value, isFalse);
await tester.tap(find.byType(SwitchListTile));
await tester.pumpAndSettle();
switchListTile = tester.widget(find.byType(SwitchListTile));
expect(switchListTile.value, isTrue);
});
}
// 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/switch_list_tile/switch_list_tile.1.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Switch aligns appropriately', (WidgetTester tester) async {
await tester.pumpWidget(
const example.SwitchListTileApp(),
);
expect(find.byType(SwitchListTile), findsNWidgets(3));
Offset tileTopLeft = tester.getTopLeft(find.byType(SwitchListTile).at(0));
Offset switchTopLeft = tester.getTopLeft(find.byType(Switch).at(0));
// The switch is centered vertically with the text.
expect(switchTopLeft - tileTopLeft, const Offset(716.0, 16.0));
tileTopLeft = tester.getTopLeft(find.byType(SwitchListTile).at(1));
switchTopLeft = tester.getTopLeft(find.byType(Switch).at(1));
// The switch is centered vertically with the text.
expect(switchTopLeft - tileTopLeft, const Offset(716.0, 30.0));
tileTopLeft = tester.getTopLeft(find.byType(SwitchListTile).at(2));
switchTopLeft = tester.getTopLeft(find.byType(Switch).at(2));
// The switch is aligned to the top vertically with the text.
expect(switchTopLeft - tileTopLeft, const Offset(716.0, 8.0));
});
testWidgets('Switches can be checked', (WidgetTester tester) async {
await tester.pumpWidget(
const example.SwitchListTileApp(),
);
expect(find.byType(SwitchListTile), findsNWidgets(3));
// All switches are on.
expect(tester.widget<Switch>(find.byType(Switch).at(0)).value, isTrue);
expect(tester.widget<Switch>(find.byType(Switch).at(1)).value, isTrue);
expect(tester.widget<Switch>(find.byType(Switch).at(2)).value, isTrue);
// Tap the first switch.
await tester.tap(find.byType(Switch).at(0));
await tester.pumpAndSettle();
// The first switch is off.
expect(tester.widget<Switch>(find.byType(Switch).at(0)).value, isFalse);
expect(tester.widget<Switch>(find.byType(Switch).at(1)).value, isTrue);
expect(tester.widget<Switch>(find.byType(Switch).at(2)).value, isTrue);
// Tap the second switch.
await tester.tap(find.byType(Switch).at(1));
await tester.pumpAndSettle();
// The first and second switches are off.
expect(tester.widget<Switch>(find.byType(Switch).at(0)).value, isFalse);
expect(tester.widget<Switch>(find.byType(Switch).at(1)).value, isFalse);
expect(tester.widget<Switch>(find.byType(Switch).at(2)).value, isTrue);
// Tap the third switch.
await tester.tap(find.byType(Switch).at(2));
await tester.pumpAndSettle();
// All switches are off.
expect(tester.widget<Switch>(find.byType(Switch).at(0)).value, isFalse);
expect(tester.widget<Switch>(find.byType(Switch).at(1)).value, isFalse);
expect(tester.widget<Switch>(find.byType(Switch).at(2)).value, isFalse);
});
}
......@@ -86,8 +86,8 @@ import 'theme_data.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.
/// This sample demonstrates how [CheckboxListTile] positions the checkbox widget
/// relative to the text in different configurations.
///
/// ** See code in examples/api/lib/material/checkbox_list_tile/checkbox_list_tile.1.dart **
/// {@end-tool}
......
......@@ -89,6 +89,13 @@ enum _SwitchListTileType { material, adaptive }
/// ** See code in examples/api/lib/material/switch_list_tile/switch_list_tile.0.dart **
/// {@end-tool}
///
/// {@tool dartpad}
/// This sample demonstrates how [SwitchListTile] positions the switch widget
/// relative to the text in different configurations.
///
/// ** See code in examples/api/lib/material/switch_list_tile/switch_list_tile.1.dart **
/// {@end-tool}
///
/// ## Semantics in SwitchListTile
///
/// Since the entirety of the SwitchListTile is interactive, it should represent
......@@ -113,7 +120,7 @@ enum _SwitchListTileType { material, adaptive }
/// LinkedLabelRadio, that includes an interactive [RichText] widget that
/// handles tap gestures.
///
/// ** See code in examples/api/lib/material/switch_list_tile/switch_list_tile.1.dart **
/// ** See code in examples/api/lib/material/switch_list_tile/custom_labeled_switch.0.dart **
/// {@end-tool}
///
/// ## SwitchListTile isn't exactly what I want
......@@ -129,7 +136,7 @@ enum _SwitchListTileType { material, adaptive }
/// Here is an example of a custom LabeledSwitch widget, but you can easily
/// make your own configurable widget.
///
/// ** See code in examples/api/lib/material/switch_list_tile/switch_list_tile.2.dart **
/// ** See code in examples/api/lib/material/switch_list_tile/custom_labeled_switch.1.dart **
/// {@end-tool}
///
/// See also:
......
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