mirror of
https://github.com/flutter/flutter
synced 2024-10-05 15:59:49 +00:00
Add Material 3 RadioListTile
example and update existing examples (#119716)
* Add Material 3 `RadioListTile` example and update existing examples * Update examples with `useMaterial3: true` and update example descriptions. * add a `ColorScheme` colour
This commit is contained in:
parent
c5e8757fcb
commit
7177c413a9
|
@ -0,0 +1,118 @@
|
|||
// 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 radio.
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() => runApp(const LabeledRadioApp());
|
||||
|
||||
class LabeledRadioApp extends StatelessWidget {
|
||||
const LabeledRadioApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('Custom Labeled Radio Sample')),
|
||||
body: const LabeledRadioExample(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class LinkedLabelRadio extends StatelessWidget {
|
||||
const LinkedLabelRadio({
|
||||
super.key,
|
||||
required this.label,
|
||||
required this.padding,
|
||||
required this.groupValue,
|
||||
required this.value,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
final String label;
|
||||
final EdgeInsets padding;
|
||||
final bool groupValue;
|
||||
final bool value;
|
||||
final ValueChanged<bool> onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: padding,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Radio<bool>(
|
||||
groupValue: groupValue,
|
||||
value: value,
|
||||
onChanged: (bool? newValue) {
|
||||
onChanged(newValue!);
|
||||
},
|
||||
),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
text: label,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
debugPrint('Label has been tapped.');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class LabeledRadioExample extends StatefulWidget {
|
||||
const LabeledRadioExample({super.key});
|
||||
|
||||
@override
|
||||
State<LabeledRadioExample> createState() => _LabeledRadioExampleState();
|
||||
}
|
||||
|
||||
class _LabeledRadioExampleState extends State<LabeledRadioExample> {
|
||||
bool _isRadioSelected = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
LinkedLabelRadio(
|
||||
label: 'First tappable label text',
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5.0),
|
||||
value: true,
|
||||
groupValue: _isRadioSelected,
|
||||
onChanged: (bool newValue) {
|
||||
setState(() {
|
||||
_isRadioSelected = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
LinkedLabelRadio(
|
||||
label: 'Second tappable label text',
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5.0),
|
||||
value: false,
|
||||
groupValue: _isRadioSelected,
|
||||
onChanged: (bool newValue) {
|
||||
setState(() {
|
||||
_isRadioSelected = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,24 +2,22 @@
|
|||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flutter code sample for [RadioListTile].
|
||||
// Flutter code sample for custom labeled radio.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() => runApp(const MyApp());
|
||||
void main() => runApp(const LabeledRadioApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
static const String _title = 'Flutter Code Sample';
|
||||
class LabeledRadioApp extends StatelessWidget {
|
||||
const LabeledRadioApp({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 MyStatefulWidget(),
|
||||
appBar: AppBar(title: const Text('Custom Labeled Radio Sample')),
|
||||
body: const LabeledRadioExample(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -68,14 +66,14 @@ class LabeledRadio extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
class MyStatefulWidget extends StatefulWidget {
|
||||
const MyStatefulWidget({super.key});
|
||||
class LabeledRadioExample extends StatefulWidget {
|
||||
const LabeledRadioExample({super.key});
|
||||
|
||||
@override
|
||||
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
|
||||
State<LabeledRadioExample> createState() => _LabeledRadioExampleState();
|
||||
}
|
||||
|
||||
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
|
||||
class _LabeledRadioExampleState extends State<LabeledRadioExample> {
|
||||
bool _isRadioSelected = false;
|
||||
|
||||
@override
|
|
@ -6,20 +6,18 @@
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() => runApp(const MyApp());
|
||||
void main() => runApp(const RadioListTileApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
static const String _title = 'Flutter Code Sample';
|
||||
class RadioListTileApp extends StatelessWidget {
|
||||
const RadioListTileApp({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 MyStatefulWidget(),
|
||||
appBar: AppBar(title: const Text('RadioListTile Sample')),
|
||||
body: const RadioListTileExample(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -27,14 +25,14 @@ class MyApp extends StatelessWidget {
|
|||
|
||||
enum SingingCharacter { lafayette, jefferson }
|
||||
|
||||
class MyStatefulWidget extends StatefulWidget {
|
||||
const MyStatefulWidget({super.key});
|
||||
class RadioListTileExample extends StatefulWidget {
|
||||
const RadioListTileExample({super.key});
|
||||
|
||||
@override
|
||||
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
|
||||
State<RadioListTileExample> createState() => _RadioListTileExampleState();
|
||||
}
|
||||
|
||||
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
|
||||
class _RadioListTileExampleState extends State<RadioListTileExample> {
|
||||
SingingCharacter? _character = SingingCharacter.lafayette;
|
||||
|
||||
@override
|
||||
|
|
|
@ -4,113 +4,73 @@
|
|||
|
||||
// Flutter code sample for [RadioListTile].
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() => runApp(const MyApp());
|
||||
void main() => runApp(const RadioListTileApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
static const String _title = 'Flutter Code Sample';
|
||||
class RadioListTileApp extends StatelessWidget {
|
||||
const RadioListTileApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: _title,
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text(_title)),
|
||||
body: const MyStatefulWidget(),
|
||||
),
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
home: const RadioListTileExample(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class LinkedLabelRadio extends StatelessWidget {
|
||||
const LinkedLabelRadio({
|
||||
super.key,
|
||||
required this.label,
|
||||
required this.padding,
|
||||
required this.groupValue,
|
||||
required this.value,
|
||||
required this.onChanged,
|
||||
});
|
||||
enum Groceries { pickles, tomato, lettuce }
|
||||
|
||||
final String label;
|
||||
final EdgeInsets padding;
|
||||
final bool groupValue;
|
||||
final bool value;
|
||||
final ValueChanged<bool> onChanged;
|
||||
class RadioListTileExample extends StatefulWidget {
|
||||
const RadioListTileExample({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: padding,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Radio<bool>(
|
||||
groupValue: groupValue,
|
||||
value: value,
|
||||
onChanged: (bool? newValue) {
|
||||
onChanged(newValue!);
|
||||
}),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
text: label,
|
||||
style: const TextStyle(
|
||||
color: Colors.blueAccent,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
debugPrint('Label has been tapped.');
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
State<RadioListTileExample> createState() => _RadioListTileExampleState();
|
||||
}
|
||||
|
||||
class MyStatefulWidget extends StatefulWidget {
|
||||
const MyStatefulWidget({super.key});
|
||||
|
||||
@override
|
||||
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
|
||||
}
|
||||
|
||||
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
|
||||
bool _isRadioSelected = false;
|
||||
class _RadioListTileExampleState extends State<RadioListTileExample> {
|
||||
Groceries? _groceryItem = Groceries.pickles;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('RadioListTile Sample')),
|
||||
body: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
LinkedLabelRadio(
|
||||
label: 'First tappable label text',
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5.0),
|
||||
value: true,
|
||||
groupValue: _isRadioSelected,
|
||||
onChanged: (bool newValue) {
|
||||
RadioListTile<Groceries>(
|
||||
value: Groceries.pickles,
|
||||
groupValue: _groceryItem,
|
||||
onChanged: (Groceries? value) {
|
||||
setState(() {
|
||||
_isRadioSelected = newValue;
|
||||
_groceryItem = value;
|
||||
});
|
||||
},
|
||||
title: const Text('Pickles'),
|
||||
subtitle: const Text('Supporting text'),
|
||||
),
|
||||
LinkedLabelRadio(
|
||||
label: 'Second tappable label text',
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5.0),
|
||||
value: false,
|
||||
groupValue: _isRadioSelected,
|
||||
onChanged: (bool newValue) {
|
||||
RadioListTile<Groceries>(
|
||||
value: Groceries.tomato,
|
||||
groupValue: _groceryItem,
|
||||
onChanged: (Groceries? value) {
|
||||
setState(() {
|
||||
_isRadioSelected = newValue;
|
||||
_groceryItem = value;
|
||||
});
|
||||
},
|
||||
title: const Text('Tomato'),
|
||||
subtitle: const Text('Longer supporting text to demonstrate how the text wraps and the radio is centered vertically with the text.'),
|
||||
),
|
||||
RadioListTile<Groceries>(
|
||||
value: Groceries.lettuce,
|
||||
groupValue: _groceryItem,
|
||||
onChanged: (Groceries? value) {
|
||||
setState(() {
|
||||
_groceryItem = value;
|
||||
});
|
||||
},
|
||||
title: const Text('Lettuce'),
|
||||
subtitle: const Text("Longer supporting text to demonstrate how the text wraps and how setting 'RadioListTile.isThreeLine = true' aligns the radio to the top vertically with the text."),
|
||||
isThreeLine: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -6,33 +6,31 @@
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() => runApp(const MyApp());
|
||||
void main() => runApp(const RadioListTileApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
static const String _title = 'Flutter Code Sample';
|
||||
class RadioListTileApp extends StatelessWidget {
|
||||
const RadioListTileApp({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 MyStatefulWidget(),
|
||||
appBar: AppBar(title: const Text('RadioListTile.toggleable Sample')),
|
||||
body: const RadioListTileExample(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyStatefulWidget extends StatefulWidget {
|
||||
const MyStatefulWidget({super.key});
|
||||
class RadioListTileExample extends StatefulWidget {
|
||||
const RadioListTileExample({super.key});
|
||||
|
||||
@override
|
||||
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
|
||||
State<RadioListTileExample> createState() => _RadioListTileExampleState();
|
||||
}
|
||||
|
||||
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
|
||||
class _RadioListTileExampleState extends State<RadioListTileExample> {
|
||||
int? groupValue;
|
||||
static const List<String> selections = <String>[
|
||||
'Hercules Mulligan',
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
// 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/radio_list_tile/custom_labeled_radio.0.dart' as example;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('LinkedLabelRadio contains RichText and Radio', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const example.LabeledRadioApp(),
|
||||
);
|
||||
|
||||
// Label text is in a RichText widget with the correct text.
|
||||
final RichText richText = tester.widget(find.byType(RichText).first);
|
||||
expect(richText.text.toPlainText(), 'First tappable label text');
|
||||
|
||||
// First Radio is initially unchecked.
|
||||
Radio<bool> radio = tester.widget(find.byType(Radio<bool>).first);
|
||||
expect(radio.value, true);
|
||||
expect(radio.groupValue, false);
|
||||
|
||||
// Last Radio is initially checked.
|
||||
radio = tester.widget(find.byType(Radio<bool>).last);
|
||||
expect(radio.value, false);
|
||||
expect(radio.groupValue, false);
|
||||
|
||||
// Tap the first radio.
|
||||
await tester.tap(find.byType(Radio<bool>).first);
|
||||
await tester.pump();
|
||||
|
||||
// First Radio is now checked.
|
||||
radio = tester.widget(find.byType(Radio<bool>).first);
|
||||
expect(radio.value, true);
|
||||
expect(radio.groupValue, true);
|
||||
|
||||
// Last Radio is now unchecked.
|
||||
radio = tester.widget(find.byType(Radio<bool>).last);
|
||||
expect(radio.value, false);
|
||||
expect(radio.groupValue, true);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
// 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/radio_list_tile/custom_labeled_radio.1.dart' as example;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Tapping LabeledRadio toggles the radio', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const example.LabeledRadioApp(),
|
||||
);
|
||||
|
||||
// First Radio is initially unchecked.
|
||||
Radio<bool> radio = tester.widget(find.byType(Radio<bool>).first);
|
||||
expect(radio.value, true);
|
||||
expect(radio.groupValue, false);
|
||||
|
||||
// Last Radio is initially checked.
|
||||
radio = tester.widget(find.byType(Radio<bool>).last);
|
||||
expect(radio.value, false);
|
||||
expect(radio.groupValue, false);
|
||||
|
||||
// Tap the first labeled radio to toggle the Radio widget.
|
||||
await tester.tap(find.byType(example.LabeledRadio).first);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// First Radio is now checked.
|
||||
radio = tester.widget(find.byType(Radio<bool>).first);
|
||||
expect(radio.value, true);
|
||||
expect(radio.groupValue, true);
|
||||
|
||||
// Last Radio is now unchecked.
|
||||
radio = tester.widget(find.byType(Radio<bool>).last);
|
||||
expect(radio.value, false);
|
||||
expect(radio.groupValue, true);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// 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/radio_list_tile/radio_list_tile.0.dart' as example;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Can update RadioListTile group value', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const example.RadioListTileApp(),
|
||||
);
|
||||
|
||||
// Find the number of RadioListTiles.
|
||||
expect(find.byType(RadioListTile<example.SingingCharacter>), findsNWidgets(2));
|
||||
|
||||
// The initial group value is lafayette for the first RadioListTile.
|
||||
RadioListTile<example.SingingCharacter> radioListTile = tester.widget(find.byType(RadioListTile<example.SingingCharacter>).first);
|
||||
expect(radioListTile.groupValue, example.SingingCharacter.lafayette);
|
||||
|
||||
// The initial group value is lafayette for the last RadioListTile.
|
||||
radioListTile = tester.widget(find.byType(RadioListTile<example.SingingCharacter>).last);
|
||||
expect(radioListTile.groupValue, example.SingingCharacter.lafayette);
|
||||
|
||||
// Tap the last RadioListTile to change the group value to jefferson.
|
||||
await tester.tap(find.byType(RadioListTile<example.SingingCharacter>).last);
|
||||
await tester.pump();
|
||||
|
||||
// The group value is now jefferson for the first RadioListTile.
|
||||
radioListTile = tester.widget(find.byType(RadioListTile<example.SingingCharacter>).first);
|
||||
expect(radioListTile.groupValue, example.SingingCharacter.jefferson);
|
||||
|
||||
// The group value is now jefferson for the last RadioListTile.
|
||||
radioListTile = tester.widget(find.byType(RadioListTile<example.SingingCharacter>).last);
|
||||
expect(radioListTile.groupValue, example.SingingCharacter.jefferson);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
// 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/radio_list_tile/radio_list_tile.1.dart' as example;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Radio aligns appropriately', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const example.RadioListTileApp(),
|
||||
);
|
||||
|
||||
expect(find.byType(RadioListTile<example.Groceries>), findsNWidgets(3));
|
||||
|
||||
Offset tileTopLeft = tester.getTopLeft(find.byType(RadioListTile<example.Groceries>).at(0));
|
||||
Offset radioTopLeft = tester.getTopLeft(find.byType(Radio<example.Groceries>).at(0));
|
||||
|
||||
// The radio is centered vertically with the text.
|
||||
expect(radioTopLeft - tileTopLeft, const Offset(16.0, 16.0));
|
||||
|
||||
tileTopLeft = tester.getTopLeft(find.byType(RadioListTile<example.Groceries>).at(1));
|
||||
radioTopLeft = tester.getTopLeft(find.byType(Radio<example.Groceries>).at(1));
|
||||
|
||||
// The radio is centered vertically with the text.
|
||||
expect(radioTopLeft - tileTopLeft, const Offset(16.0, 30.0));
|
||||
|
||||
tileTopLeft = tester.getTopLeft(find.byType(RadioListTile<example.Groceries>).at(2));
|
||||
radioTopLeft = tester.getTopLeft(find.byType(Radio<example.Groceries>).at(2));
|
||||
|
||||
// The radio is aligned to the top vertically with the text.
|
||||
expect(radioTopLeft - tileTopLeft, const Offset(16.0, 8.0));
|
||||
});
|
||||
|
||||
testWidgets('Radios can be checked', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const example.RadioListTileApp(),
|
||||
);
|
||||
|
||||
expect(find.byType(RadioListTile<example.Groceries>), findsNWidgets(3));
|
||||
final Finder radioListTile = find.byType(RadioListTile<example.Groceries>);
|
||||
|
||||
// Initially the first radio is checked.
|
||||
expect(
|
||||
tester.widget<RadioListTile<example.Groceries>>(radioListTile.at(0)).groupValue,
|
||||
example.Groceries.pickles,
|
||||
);
|
||||
expect(
|
||||
tester.widget<RadioListTile<example.Groceries>>(radioListTile.at(1)).groupValue,
|
||||
example.Groceries.pickles,
|
||||
);
|
||||
expect(
|
||||
tester.widget<RadioListTile<example.Groceries>>(radioListTile.at(2)).groupValue,
|
||||
example.Groceries.pickles,
|
||||
);
|
||||
|
||||
// Tap the second radio.
|
||||
await tester.tap(find.byType(Radio<example.Groceries>).at(1));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// The second radio is checked.
|
||||
expect(
|
||||
tester.widget<RadioListTile<example.Groceries>>(radioListTile.at(0)).groupValue,
|
||||
example.Groceries.tomato,
|
||||
);
|
||||
expect(
|
||||
tester.widget<RadioListTile<example.Groceries>>(radioListTile.at(1)).groupValue,
|
||||
example.Groceries.tomato,
|
||||
);
|
||||
expect(
|
||||
tester.widget<RadioListTile<example.Groceries>>(radioListTile.at(2)).groupValue,
|
||||
example.Groceries.tomato,
|
||||
);
|
||||
|
||||
// Tap the third radio.
|
||||
await tester.tap(find.byType(Radio<example.Groceries>).at(2));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// The third radio is checked.
|
||||
expect(
|
||||
tester.widget<RadioListTile<example.Groceries>>(radioListTile.at(0)).groupValue,
|
||||
example.Groceries.lettuce,
|
||||
);
|
||||
expect(
|
||||
tester.widget<RadioListTile<example.Groceries>>(radioListTile.at(1)).groupValue,
|
||||
example.Groceries.lettuce,
|
||||
);
|
||||
expect(
|
||||
tester.widget<RadioListTile<example.Groceries>>(radioListTile.at(2)).groupValue,
|
||||
example.Groceries.lettuce,
|
||||
);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// 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/radio_list_tile/radio_list_tile.toggleable.0.dart' as example;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('RadioListTile is toggleable', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const example.RadioListTileApp(),
|
||||
);
|
||||
|
||||
// Initially the third radio button is not selected.
|
||||
Radio<int> radio = tester.widget(find.byType(Radio<int>).at(2));
|
||||
expect(radio.value, 2);
|
||||
expect(radio.groupValue, null);
|
||||
|
||||
// Tap the third radio button.
|
||||
await tester.tap(find.text('Philip Schuyler'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// The third radio button is now selected.
|
||||
radio = tester.widget(find.byType(Radio<int>).at(2));
|
||||
expect(radio.value, 2);
|
||||
expect(radio.groupValue, 2);
|
||||
|
||||
// Tap the third radio button again.
|
||||
await tester.tap(find.text('Philip Schuyler'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// The third radio button is now unselected.
|
||||
radio = tester.widget(find.byType(Radio<int>).at(2));
|
||||
expect(radio.value, 2);
|
||||
expect(radio.groupValue, null);
|
||||
});
|
||||
}
|
|
@ -86,6 +86,13 @@ import 'theme_data.dart';
|
|||
/// ** See code in examples/api/lib/material/radio_list_tile/radio_list_tile.0.dart **
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// {@tool dartpad}
|
||||
/// This sample demonstrates how [RadioListTile] positions the radio widget
|
||||
/// relative to the text in different configurations.
|
||||
///
|
||||
/// ** See code in examples/api/lib/material/radio_list_tile/radio_list_tile.1.dart **
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// ## Semantics in RadioListTile
|
||||
///
|
||||
/// Since the entirety of the RadioListTile is interactive, it should represent
|
||||
|
@ -110,7 +117,7 @@ import 'theme_data.dart';
|
|||
/// LinkedLabelRadio, that includes an interactive [RichText] widget that
|
||||
/// handles tap gestures.
|
||||
///
|
||||
/// ** See code in examples/api/lib/material/radio_list_tile/radio_list_tile.1.dart **
|
||||
/// ** See code in examples/api/lib/material/radio_list_tile/custom_labeled_radio.0.dart **
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// ## RadioListTile isn't exactly what I want
|
||||
|
@ -126,7 +133,7 @@ import 'theme_data.dart';
|
|||
/// Here is an example of a custom LabeledRadio widget, but you can easily
|
||||
/// make your own configurable widget.
|
||||
///
|
||||
/// ** See code in examples/api/lib/material/radio_list_tile/radio_list_tile.2.dart **
|
||||
/// ** See code in examples/api/lib/material/radio_list_tile/custom_labeled_radio.1.dart **
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// See also:
|
||||
|
|
Loading…
Reference in a new issue