サンプルがわかりずらい?
Flutterのラジオボタンの使い方を見てみると、わかりにくくて、参考になる情報がなくて困った😅
enumは必要なのか?
こちらが公式
過去に試したがうまく使えない?
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
static const String _title = 'Flutter Code Sample';
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const Center(
child: MyStatefulWidget(),
),
),
);
}
}
enum SingingCharacter { lafayette, jefferson }
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
SingingCharacter? _character = SingingCharacter.lafayette;
Widget build(BuildContext context) {
return Column(
children: <Widget>[
ListTile(
title: const Text('Lafayette'),
leading: Radio<SingingCharacter>(
value: SingingCharacter.lafayette,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
),
ListTile(
title: const Text('Thomas Jefferson'),
leading: Radio<SingingCharacter>(
value: SingingCharacter.jefferson,
groupValue: _character,
onChanged: (SingingCharacter? value) {
setState(() {
_character = value;
});
},
),
),
],
);
}
}
でもわかりやすい使い方を教えてくれてる動画があった!
こちらを参考にString型とint型のデータをFirestoreに、保存するラジオボタンの機能を作ってみました!
用意するのは、変数だけ。
radio_test/radio_menu.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class RadioMenu extends StatefulWidget {
const RadioMenu({Key? key}) : super(key: key);
State<RadioMenu> createState() => _RadioMenuState();
}
class _RadioMenuState extends State<RadioMenu> {
int _value = 1; // int型の変数.
String _text = ''; // String型の変数.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('RadioMenu'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// int型のラジオボタン.
Row(
children: [
Radio(
value: 1,
groupValue: _value,
onChanged: (value) {
setState(() {
_value = value!;
});
}),
SizedBox(width: 10.0),
Text('Radio1'),
Radio(
value: 2,
groupValue: _value,
onChanged: (value) {
setState(() {
_value = value!;
});
}),
SizedBox(width: 10.0),
Text('Radio2'),
Radio(
value: 3,
groupValue: _value,
onChanged: (value) {
setState(() {
_value = value!;
});
}),
SizedBox(width: 10.0),
Text('Radio3'),
],
),
SizedBox(height: 20),
// String型のラジオボタン.
Row(
children: [
Radio(
value: 'Radio1',
groupValue: _text,
onChanged: (value) {
setState(() {
_text = value!;
});
}),
SizedBox(width: 10.0),
Text('Radio1'),
Radio(
value: 'Radio2',
groupValue: _text,
onChanged: (value) {
setState(() {
_text = value!;
});
}),
SizedBox(width: 10.0),
Text('Radio2'),
Radio(
value: 'Radio3',
groupValue: _text,
onChanged: (value) {
setState(() {
_text = value!;
});
}),
SizedBox(width: 10.0),
Text('Radio3'),
],
),
ElevatedButton(
onPressed: () async {
// int型か調べる.
print(_value.runtimeType);
print(_value);
// String型か調べる.
print(_text.runtimeType);
print(_text);
// FirestoreにintとStringのデータを保存する.
await FirebaseFirestore.instance.collection('radio').add({
'int': _value,
'String': _text,
});
},
child: const Text('save'))
],
),
);
}
}
main.dart
import 'dart:developer';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:state_tutorial/radio_test/radio_menu.dart';
import 'package:state_tutorial/reference_page/blog_page.dart';
import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const RadioMenu(),
);
}
}
まとめ
お問い合わせフォームやアンケートの画面で、ラジオボタンがよくあるので試しに作ってみたいなと思いやってみました。
他にもチェックボックスやスライダーなど色々試してみて、入力フォームのバリエーションを増やしたいなと考えてます。
Riverpodで書き直すのもやってみました。
main.dart
import 'dart:developer';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:state_tutorial/radio_test/radio_menu.dart';
import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const RadioMenu(),
);
}
}
radio_test/radio_menu.dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final intProvider = StateProvider<int>((ref) => 0);
final stringProvider = StateProvider<String>((ref) => '');
class RadioMenu extends ConsumerWidget {
const RadioMenu({Key? key}) : super(key: key);
Widget build(BuildContext context, WidgetRef ref) {
// 状態管理している値を取得するプロバイダー.
final _value = ref.watch(intProvider);
final _text = ref.watch(stringProvider);
// 状態管理している値を操作するプロバイダー.
final _intValue = ref.watch(intProvider.notifier);
final _textValue = ref.watch(stringProvider.notifier);
return Scaffold(
appBar: AppBar(
title: const Text('RadioMenu'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// int型のラジオボタン.
Row(
children: [
Radio(
value: 1,
groupValue: _value, // 状態を表示する.
onChanged: (value) {
_intValue.state = value!; // 状態を操作する.
}),
SizedBox(width: 10.0),
Text('Radio1'),
Radio(
value: 2,
groupValue: _value,
onChanged: (value) {
_intValue.state = value!;
}),
SizedBox(width: 10.0),
Text('Radio2'),
Radio(
value: 3,
groupValue: _value,
onChanged: (value) {
_intValue.state = value!;
}),
SizedBox(width: 10.0),
Text('Radio3'),
],
),
SizedBox(height: 20),
// String型のラジオボタン.
Row(
children: [
Radio(
value: 'Radio1',
groupValue: _text,
onChanged: (value) {
_textValue.state = value!;
}),
SizedBox(width: 10.0),
Text('Radio1'),
Radio(
value: 'Radio2',
groupValue: _text,
onChanged: (value) {
_textValue.state = value!;
}),
SizedBox(width: 10.0),
Text('Radio2'),
Radio(
value: 'Radio3',
groupValue: _text,
onChanged: (value) {
_textValue.state = value!;
}),
SizedBox(width: 10.0),
Text('Radio3'),
],
),
ElevatedButton(
onPressed: () async {
// FirestoreにintとStringのデータを保存する.
await FirebaseFirestore.instance.collection('radio').add({
'int': _value,
'String': _text,
});
},
child: const Text('save'))
],
),
);
}
}
Discussion