[Widget]ラジオボタンを使う

動作環境: Flutter 2.8.1 Dart 2.15.1
LINEでこのページを共有するTwitterでこのページを共有するこのページをはてなブックマークに追加

Flutterでラジオボタンを使うときはRadioを使います。
以下、サンプルコードです。

lib/main.dart
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
RamenKind yourChoice = RamenKind.miso;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('サンプル'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RadioButton(
label: 'みそ',
groupValue: yourChoice,
value: RamenKind.miso,
onChanged: (newValue) => setState(() {
yourChoice = newValue;
}),
),
RadioButton(
label: 'しお',
groupValue: yourChoice,
value: RamenKind.sio,
onChanged: (newValue) => setState(() {
yourChoice = newValue;
}),
),
RadioButton(
label: 'しょうゆ',
groupValue: yourChoice,
value: RamenKind.shoYu,
onChanged: (newValue) => setState(() {
yourChoice = newValue;
}),
),
Text('$yourChoiceを選択しています'),
],
),
),
),
);
}
}
enum RamenKind { miso, sio, shoYu }
class RadioButton extends StatelessWidget {
const RadioButton({
Key? key,
required this.label,
required this.groupValue,
required this.value,
required this.onChanged,
}) : super(key: key);
final String label;
final RamenKind groupValue;
final RamenKind value;
final ValueChanged<RamenKind> onChanged;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
if (value == groupValue) {
return;
}
onChanged(value);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Radio<RamenKind>(
groupValue: groupValue,
value: value,
onChanged: (RamenKind? newValue) {
onChanged(newValue!);
},
),
Text(label)
],
),
);
}
}

まず、ラジオボタンの選択肢をenumで定義しておきます。
今回はラーメン3種類にしました。

enum RamenKind { miso, sio, shoYu }

同じ仕様のラジオボタンを三つ配置することになるため、ラジオボタンをWidgetとして作成して使い回すようにしようと思います。
以下のようにRadioButtonを作成しました。

lib/main.dart
class RadioButton extends StatelessWidget {
const RadioButton({
Key? key,
required this.label,
required this.groupValue,
required this.value,
required this.onChanged,
}) : super(key: key);
final String label;
final RamenKind groupValue;
final RamenKind value;
final ValueChanged<RamenKind> onChanged;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
if (value == groupValue) {
return;
}
onChanged(value);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Radio<RamenKind>(
groupValue: groupValue,
value: value,
onChanged: (RamenKind? newValue) {
onChanged(newValue!);
},
),
Text(label)
],
),
);
}
}

88行目でRadioを使っています。
ラジオボタンを配置する場合、多くのケースではボタンの脇にテキストを置くことになると思います。
しかし、そのままだとテキストをタップしてもボタンを選択したことになりません。

そこで78行目のようにGestureDetectorで囲むことでボタンとテキスト全体がユーザーのタップに反応するようにしました。

*「Run」を押すと実行できます。