Skip to content

Commit 84078c8

Browse files
Create CupertinoRadio Widget (#123296)
Create CupertinoRadio Widget
1 parent 8afd600 commit 84078c8

File tree

7 files changed

+872
-0
lines changed

7 files changed

+872
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/cupertino.dart';
6+
7+
/// Flutter code sample for [CupertinoRadio].
8+
9+
void main() => runApp(const CupertinoRadioApp());
10+
11+
class CupertinoRadioApp extends StatelessWidget {
12+
const CupertinoRadioApp({super.key});
13+
14+
static const String _title = 'CuptertinoRadio Example';
15+
16+
@override
17+
Widget build(BuildContext context) {
18+
return const CupertinoApp(
19+
theme: CupertinoThemeData(brightness: Brightness.light),
20+
home: CupertinoPageScaffold(
21+
navigationBar: CupertinoNavigationBar(
22+
middle: Text(_title),
23+
),
24+
child: SafeArea(
25+
child: CupertinoRadioExample(),
26+
),
27+
),
28+
);
29+
}
30+
}
31+
32+
enum SingingCharacter { lafayette, jefferson }
33+
34+
class CupertinoRadioExample extends StatefulWidget {
35+
const CupertinoRadioExample({super.key});
36+
37+
@override
38+
State<CupertinoRadioExample> createState() => _CupertinoRadioExampleState();
39+
}
40+
41+
class _CupertinoRadioExampleState extends State<CupertinoRadioExample> {
42+
SingingCharacter? _character = SingingCharacter.lafayette;
43+
44+
@override
45+
Widget build(BuildContext context) {
46+
return CupertinoListSection(
47+
children: <Widget>[
48+
CupertinoListTile(
49+
title: const Text('Lafayette'),
50+
leading: CupertinoRadio<SingingCharacter>(
51+
value: SingingCharacter.lafayette,
52+
groupValue: _character,
53+
onChanged: (SingingCharacter? value) {
54+
setState(() {
55+
_character = value;
56+
});
57+
},
58+
),
59+
),
60+
CupertinoListTile(
61+
title: const Text('Thomas Jefferson'),
62+
leading: CupertinoRadio<SingingCharacter>(
63+
value: SingingCharacter.jefferson,
64+
groupValue: _character,
65+
onChanged: (SingingCharacter? value) {
66+
setState(() {
67+
_character = value;
68+
});
69+
},
70+
),
71+
),
72+
],
73+
);
74+
}
75+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/cupertino.dart';
6+
7+
/// Flutter code sample for [CupertinoRadio.toggleable].
8+
9+
void main() => runApp(const CupertinoRadioApp());
10+
11+
class CupertinoRadioApp extends StatelessWidget {
12+
const CupertinoRadioApp({super.key});
13+
14+
static const String _title = 'CuptertinoRadio Toggleable Example';
15+
16+
@override
17+
Widget build(BuildContext context) {
18+
return const CupertinoApp(
19+
home: CupertinoPageScaffold(
20+
navigationBar: CupertinoNavigationBar(
21+
middle: Text(_title),
22+
),
23+
child: SafeArea(
24+
child: CupertinoRadioExample(),
25+
),
26+
),
27+
);
28+
}
29+
}
30+
31+
enum SingingCharacter { mulligan, hamilton }
32+
33+
class CupertinoRadioExample extends StatefulWidget {
34+
const CupertinoRadioExample({super.key});
35+
36+
@override
37+
State<CupertinoRadioExample> createState() => _CupertinoRadioExampleState();
38+
}
39+
40+
class _CupertinoRadioExampleState extends State<CupertinoRadioExample> {
41+
SingingCharacter? _character = SingingCharacter.mulligan;
42+
43+
@override
44+
Widget build(BuildContext context) {
45+
return CupertinoListSection(
46+
children: <Widget>[
47+
CupertinoListTile(
48+
title: const Text('Hercules Mulligan'),
49+
leading: CupertinoRadio<SingingCharacter>(
50+
value: SingingCharacter.mulligan,
51+
groupValue: _character,
52+
// TRY THIS: Try setting the toggleable value to false and
53+
// see how that changes the behavior of the widget.
54+
toggleable: true,
55+
onChanged: (SingingCharacter? value) {
56+
setState(() {
57+
_character = value;
58+
});
59+
},
60+
),
61+
),
62+
CupertinoListTile(
63+
title: const Text('Eliza Hamilton'),
64+
leading: CupertinoRadio<SingingCharacter>(
65+
value: SingingCharacter.hamilton,
66+
groupValue: _character,
67+
toggleable: true,
68+
onChanged: (SingingCharacter? value) {
69+
setState(() {
70+
_character = value;
71+
});
72+
},
73+
),
74+
),
75+
],
76+
);
77+
}
78+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/cupertino.dart';
6+
import 'package:flutter_api_samples/cupertino/radio/cupertino_radio.0.dart' as example;
7+
import 'package:flutter_test/flutter_test.dart';
8+
9+
void main() {
10+
testWidgets('Has 2 CupertinoRadio widgets', (WidgetTester tester) async {
11+
await tester.pumpWidget(
12+
const example.CupertinoRadioApp(),
13+
);
14+
15+
expect(find.byType(CupertinoRadio<example.SingingCharacter>), findsNWidgets(2));
16+
17+
CupertinoRadio<example.SingingCharacter> radio = tester.widget(find.byType(CupertinoRadio<example.SingingCharacter>).first);
18+
expect(radio.groupValue, example.SingingCharacter.lafayette);
19+
20+
radio = tester.widget(find.byType(CupertinoRadio<example.SingingCharacter>).last);
21+
expect(radio.groupValue, example.SingingCharacter.lafayette);
22+
23+
await tester.tap(find.byType(CupertinoRadio<example.SingingCharacter>).last);
24+
await tester.pumpAndSettle();
25+
26+
radio = tester.widget(find.byType(CupertinoRadio<example.SingingCharacter>).last);
27+
expect(radio.groupValue, example.SingingCharacter.jefferson);
28+
29+
radio = tester.widget(find.byType(CupertinoRadio<example.SingingCharacter>).first);
30+
expect(radio.groupValue, example.SingingCharacter.jefferson);
31+
});
32+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/cupertino.dart';
6+
import 'package:flutter_api_samples/cupertino/radio/cupertino_radio.toggleable.0.dart' as example;
7+
import 'package:flutter_test/flutter_test.dart';
8+
9+
void main() {
10+
testWidgets('Has 2 CupertinoRadio widgets that can be toggled off', (WidgetTester tester) async {
11+
await tester.pumpWidget(
12+
const example.CupertinoRadioApp(),
13+
);
14+
15+
expect(find.byType(CupertinoRadio<example.SingingCharacter>), findsNWidgets(2));
16+
17+
CupertinoRadio<example.SingingCharacter> radio = tester.widget(find.byType(CupertinoRadio<example.SingingCharacter>).first);
18+
expect(radio.groupValue, example.SingingCharacter.mulligan);
19+
20+
radio = tester.widget(find.byType(CupertinoRadio<example.SingingCharacter>).last);
21+
expect(radio.groupValue, example.SingingCharacter.mulligan);
22+
23+
await tester.tap(find.byType(CupertinoRadio<example.SingingCharacter>).last);
24+
await tester.pumpAndSettle();
25+
26+
radio = tester.widget(find.byType(CupertinoRadio<example.SingingCharacter>).last);
27+
expect(radio.groupValue, example.SingingCharacter.hamilton);
28+
29+
radio = tester.widget(find.byType(CupertinoRadio<example.SingingCharacter>).first);
30+
expect(radio.groupValue, example.SingingCharacter.hamilton);
31+
32+
await tester.tap(find.byType(CupertinoRadio<example.SingingCharacter>).last);
33+
await tester.pumpAndSettle();
34+
35+
radio = tester.widget(find.byType(CupertinoRadio<example.SingingCharacter>).last);
36+
expect(radio.groupValue, null);
37+
});
38+
}

packages/flutter/lib/cupertino.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export 'src/cupertino/magnifier.dart';
5050
export 'src/cupertino/nav_bar.dart';
5151
export 'src/cupertino/page_scaffold.dart';
5252
export 'src/cupertino/picker.dart';
53+
export 'src/cupertino/radio.dart';
5354
export 'src/cupertino/refresh.dart';
5455
export 'src/cupertino/route.dart';
5556
export 'src/cupertino/scrollbar.dart';

0 commit comments

Comments
 (0)