I have implemented three radio buttons in my flutter project. But after executing the application, none of the radio buttons are showing selected. Can anyone help me where I am getting wrong please !
There is no radio button is getting selected although I click on it. I am unable to figure out the reason. Please help me solving it. Here is my code :
class AdminHomeContent extends StatefulWidget {
#override
_AdminHomeContentState createState() => _AdminHomeContentState();
}
class _AdminHomeContentState extends State<AdminHomeContent> {
static final Map<String, Color> options = {
'All': Colors.black, 'Cancelled':Colors.red,
'Pending': Colors.yellow, 'Visited': Colors.green[900],
};
List keyList = options.keys.toList();
List keyColor = options.values.toList();
String selectedOption = 'All';
int groupValue = 0 ;
void buttonValue(int v){
setState(() {
groupValue = v ;
});
}
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider<PatientDataNotifier>(
create: (context) => PatientDataNotifier(),
child: MaterialApp(
home: Scaffold(
// some of my other codes
----------
-----------
//method that defines three radio buttons
Future<dynamic> getStatus(BuildContext context) {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: SingleChildScrollView(
child: Container(
child: Column(
children: [
Row(
children: [
Radio(value: 1,
activeColor: Colors.blue,
groupValue: groupValue,
onChanged: (int v){
print(v);
buttonValue(v);
}
),
Text(keyList[2] , style: TextStyle(color: keyColor[2]),)
],
),
Row(
children: [
Radio(value: 2,
activeColor: Colors.blue,
groupValue: groupValue,
onChanged: (int v) {
print(v);
buttonValue(v);
}
),
Text(keyList[3] , style: TextStyle(color: keyColor[3]))
],
),
Row(
children: [
Radio(value: 3,
activeColor: Colors.blue,
groupValue: groupValue,
onChanged: (int v) {
print(v);
buttonValue(v);
}
),
Text(keyList[1] , style: TextStyle(color: keyColor[1]))
],
)
],
),
),
),
);
}
);
}
// some codes
------------------
-----------------
//calling the getStatus() inside the onTap() property of a Text
GestureDetector(
child: Text(patient.status,
style: getTextStyle('Poppins-Regular',15.0, FontWeight.bold, options[status]),
),
onTap: () async{
await getStatus(context);
},
),
}
}
None of the radio buttons are getting selected even after clicking on it. Please help me solving it.
First of all, none of Radio is selected by default because your initial groupValue is 0 and none of your Radio has this value.
Here a fully example of working Radio
class MyRadio extends StatefulWidget {
#override
_MyRadioState createState() => _MyRadioState();
}
int groupValue = 1;
class _MyRadioState extends State<MyRadio> {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Column(
children: [
Radio(
value: 1,
activeColor: Colors.blue,
groupValue: groupValue,
onChanged: (int v) {
buttonValue(v);
},
),
Radio(
value: 2,
activeColor: Colors.blue,
groupValue: groupValue,
onChanged: (int v) {
buttonValue(v);
},
),
Radio(
value: 3,
activeColor: Colors.blue,
groupValue: groupValue,
onChanged: (int v) {
buttonValue(v);
},
),
],
),
),
),
);
}
void buttonValue(int v) {
setState(() {
groupValue = v;
});
}
}
Related
In my code can select multiple checkboxes, but I want to print the selected checkboxes titles.And also then application run checkboxes are unselecting ( checkboxes values are bool = false)
Ex: Like as this Image I selected dart and java checkboxes so I want to insert those names in the firestore.I have no idea how to equal the check box value to string values.
How to insert that values?
code
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class HomePageWidget extends StatefulWidget {
const HomePageWidget({Key? key}) : super(key: key);
#override
_HomePageWidgetState createState() => _HomePageWidgetState();
}
class _HomePageWidgetState extends State<HomePageWidget> {
bool? checkboxListTileValue1;
bool? checkboxListTileValue2;
bool? checkboxListTileValue3;
bool? checkboxListTileValue4;
bool? checkboxListTileValue5;
String checkboxListTileValue1 = "c++"
String checkboxListTileValue2 = "c"
String checkboxListTileValue3 = "java"
String checkboxListTileValue4 = "react"
String checkboxListTileValue5 = "dart"
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text(
'Page Title',
),
actions: [],
centerTitle: false,
elevation: 2,
),
body: SafeArea(
child: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Theme(
data: ThemeData(
unselectedWidgetColor: Color(0xFF95A1AC),
),
child: CheckboxListTile(
value: checkboxListTileValue1 ??= false,
onChanged: (newValue) async {
setState(() => checkboxListTileValue1 = newValue!);
},
title: Text(
'c++',
),
tileColor: Color(0xFFF5F5F5),
dense: false,
controlAffinity: ListTileControlAffinity.trailing,
),
),
Theme(
data: ThemeData(
unselectedWidgetColor: Color(0xFF95A1AC),
),
child: CheckboxListTile(
value: checkboxListTileValue2 ??= false,
onChanged: (newValue) async {
setState(() => checkboxListTileValue2 = newValue!);
},
title: Text(
'c',
),
tileColor: Color(0xFFF5F5F5),
dense: false,
controlAffinity: ListTileControlAffinity.trailing,
),
),
Theme(
data: ThemeData(
unselectedWidgetColor: Color(0xFF95A1AC),
),
child: CheckboxListTile(
value: checkboxListTileValue3 ??= false,
onChanged: (newValue) async {
setState(() => checkboxListTileValue3 = newValue!);
},
title: Text(
'java',
),
tileColor: Color(0xFFF5F5F5),
dense: false,
controlAffinity: ListTileControlAffinity.trailing,
),
),
Theme(
data: ThemeData(
unselectedWidgetColor: Color(0xFF95A1AC),
),
child: CheckboxListTile(
value: checkboxListTileValue4 ??= false,
onChanged: (newValue) async {
setState(() => checkboxListTileValue4 = newValue!);
},
title: Text(
'react',
),
tileColor: Color(0xFFF5F5F5),
dense: false,
controlAffinity: ListTileControlAffinity.trailing,
),
),
Theme(
data: ThemeData(
unselectedWidgetColor: Color(0xFF95A1AC),
),
child: CheckboxListTile(
value: checkboxListTileValue5 ??= false,
onChanged: (newValue) async {
setState(() => checkboxListTileValue5 = newValue!);
},
title: Text(
'dart',
),
tileColor: Color(0xFFF5F5F5),
dense: false,
controlAffinity: ListTileControlAffinity.trailing,
),
),
ElevatedButton(onPressed: press(), child: Text('submit'))
],
),
),
),
);
}
press() {
FirebaseFirestore.instance
.collection("users")
.doc()
.set({
"checkboxes": checkboxListTileValue1 + checkboxListTileValue2 + checkboxListTileValue3 + checkboxListTileValue4 + checkboxListTileValue5,
});
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const HomePageWidget()),
);
}
}
errors
this
First you need to define class model for your checkbox like this:
class CheckBoxModel {
final String title;
final bool value;
CheckBoxModel({required this.title, required this.value});
}
then use it like this:
class TestingDesign2 extends StatefulWidget {
const TestingDesign2({super.key});
#override
State<TestingDesign2> createState() => _TestingDesign2State();
}
class _TestingDesign2State extends State<TestingDesign2> {
List<CheckBoxModel> checkboxes = [
CheckBoxModel(title: 'C++', value: false),
CheckBoxModel(title: 'java', value: false),
CheckBoxModel(title: 'C', value: false),
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
return buildCheckBox(checkboxes[index], index);
},
itemCount: checkboxes.length,
),
),
ElevatedButton(onPressed: press(), child: Text('submit'))
],
),
);
}
buildCheckBox(CheckBoxModel checkbox, int index) {
return Theme(
data: ThemeData(
unselectedWidgetColor: Color(0xFF95A1AC),
),
child: CheckboxListTile(
value: checkbox.value,
onChanged: (newValue) async {
setState(() => checkboxes[index] =
CheckBoxModel(title: checkbox.title, value: newValue!));
},
title: Text(
checkbox.title,
style: TextStyle(
fontSize: 12,
),
),
tileColor: Colors.transparent,
dense: false,
controlAffinity: ListTileControlAffinity.trailing,
),
);
}
press() {
List<CheckBoxModel> checked =
checkboxes.where((element) => element.value).toList();
String result = '';
checked.forEach((element) {
result = result + element.title;
});
FirebaseFirestore.instance.collection("users").doc().set({
"checkboxes": result,
});
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const HomePageWidget()),
);
}
}
Here's my code
DropdownButton<int>(
value: map['completedVersion'].toInt(), //selected
elevation: 16,
style: TextStyle(color: Theme.of(context).accentColor),
underline: Container(
height: 2,
color: Colors.blueAccent,
),
onChanged: (int? newValue) {
versionInput.text = newValue.toString();
},
items: [for (var i = map['completedVersion'].toInt() as int; i <= map['requiredVersion']; i++) i]
.map<DropdownMenuItem<int>>((int value) {
return DropdownMenuItem<int>(
value: value,
child: Text(value.toString()),
);
}).toList(),
)
Class level declaration
TextEditingController versionInput = TextEditingController();
#override
void initState() {
versionInput.text = map['completedVersion'].toString(); //set the initial value of text field
super.initState();
}
Here's the behavior
It doesn't let me select any other value (eg: 4,5,6). I do see that he onChanged() method is hit when I put in a break point. But I'm not sure why the selection goes back to the original value.
TextEditingValue
class Example extends StatelessWidget {
Example({Key? key}) : super(key: key);
TextEditingController versionInput = TextEditingController(text: "2");
#override
Widget build(BuildContext context) {
return Column(
children: [
ValueListenableBuilder(
valueListenable: versionInput,
builder: (BuildContext context, TextEditingValue selectedValue, Widget? child) {
return DropdownButton<int>(
value: int.parse(selectedValue.text),
elevation: 16,
style: TextStyle(color: Theme.of(context).accentColor),
underline: Container(
height: 2,
color: Colors.blueAccent,
),
onChanged: (value) {},
items: [for (var i = 0 as int; i <= 6; i++) i].map<DropdownMenuItem<int>>((int value) {
return DropdownMenuItem<int>(
value: value,
child: Text(value.toString()),
onTap: () {
versionInput.text = value.toString();
},
);
}).toList(),
);
},
),
],
);
}
}
If you really use the TextEditingController without a text field and you don't need it, you can use it directly in the ValueNotifier.
ValueNotifier
class Example extends StatelessWidget {
Example({Key? key}) : super(key: key);
ValueNotifier<int> versionInput = ValueNotifier<int>(2); // initialValue
#override
Widget build(BuildContext context) {
return Column(
children: [
ValueListenableBuilder(
valueListenable: versionInput,
builder: (BuildContext context, int selectedValue, Widget? child) {
return DropdownButton<int>(
value: selectedValue,
elevation: 16,
style: TextStyle(color: Theme.of(context).accentColor),
underline: Container(
height: 2,
color: Colors.blueAccent,
),
onChanged: (value) {},
items: [for (var i = 0 as int; i <= 6; i++) i].map<DropdownMenuItem<int>>((int value) {
return DropdownMenuItem<int>(
value: value,
child: Text(value.toString()),
onTap: () {
versionInput.value = value;
},
);
}).toList(),
);
},
),
],
);
}
}
You have to change two things :
1- value: map['completedVersion'].toInt(), ==> value: versionInput.text,
2-
onChanged: (newValue) {
setState(() {
versionInput.text = newValue.toString();
});
},
this should work:
#override
Widget build(BuildContext context) {
return Column(
children: [
ValueListenableBuilder(
valueListenable: versionInput,
builder: (BuildContext context, TextEditingValue selectedValue, Widget? child) {
return DropdownButton<int>(
hint: Text(
int.parse(selectedValue.text) ?? '3'
),
elevation: 16,
style: TextStyle(color: Theme.of(context).accentColor),
underline: Container(
height: 2,
color: Colors.blueAccent,
),
onChanged: (int? newValue) {
if(newValue != null){
setState(()=> versionInput.text = newValue.toString());
}
},
items: [for (var i = 0; i <= 6; i++) i].map<DropdownMenuItem<int>>((int value) {
return DropdownMenuItem<int>(
value: value,
child: Text(value.toString()),
onTap: () {
versionInput.text = value.toString();
},
);
}).toList(),
);
},
),
],
);
}
}
I have trouble changing Radio List Tile icon color.
I tried to use ListTileTheme but not worked.
By the way, I'm using RadioListTile in a dialog but I don't think that this affects it.
Code.
ListTileTheme(
iconColor: AppColors.green,
textColor: AppColors.green,
child: SimpleDialog(
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius
.circular(10),
),
title: Text(
"Select Restaurant",
style: Theme.of(context)
.textTheme
.headline3,
textAlign:
TextAlign.center,
),
children: [
Divider(),
RadioListTile(
title: const Text(
'Name and Address'),
value: 1,
groupValue:
_isRadioSelected,
onChanged: (v) {
setState(() {
_isRadioSelected =
v;
});
},
),
],
),
);
Theme(
data: Theme.of(context).copyWith(
unselectedWidgetColor: Colors.green,
disabledColor: Colors.green
),
child: RadioListTile(
title: const Text('Name and Address'),
value: 1,
groupValue: _isRadioSelected,
onChanged: (v) {
setState(() {
_isRadioSelected = v;
});
},
),
)
Use Theme for change some theme param in current widget.
You can build a custom simple radio list widget by using the below code.
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class GroupModel {
String text;
int index;
bool selected;
GroupModel({this.text, this.index, this.selected});
}
class MyApp extends StatefulWidget {
#override
_State createState() => new _State();
}
class _State extends State<MyApp> {
int _value2 = 0;
List<GroupModel> _group = [
GroupModel(text: "Item 1", index: 1, selected: true),
GroupModel(text: "Item 2", index: 2, selected: false),
GroupModel(text: "Item 3", index: 3, selected: false),
];
Widget makeRadioTileList() {
List<Widget> list = new List<Widget>();
for (int i = 0; i < _group.length; i++) {
list.add(new RadioListTile(
value: _group[i].index,
groupValue: _value2,
selected: _group[i].selected,
onChanged: (val) {
setState(() {
for (int i = 0; i < _group.length; i++) {
_group[i].selected = false;
}
_value2 = val;
_group[i].selected = true;
});
},
activeColor: Colors.purple,
controlAffinity: ListTileControlAffinity.trailing,
title: new Text(
' ${_group[i].text}',
style: TextStyle(
color: _group[i].selected ? Colors.black : Colors.grey,
fontWeight:
_group[i].selected ? FontWeight.bold : FontWeight.normal),
),
));
}
Column column = new Column(
children: list,
);
return column;
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('RadioListTile Example'),
),
body: new Container(
padding: new EdgeInsets.all(30.0),
child: new Center(
child: new Column(
children: <Widget>[makeRadioTileList()],
),
),
),
);
}
}
I need to pass the radio button value stored in variable radioValue from homepage.dart to class DialogFactory in dialogfactory.dart, where I will use it. The current radioValue value should be passed when I press a button which calls function _openDialog(), which is meant to open the alert dialog with the selected style.
======================================
homepage.dart
[...]
class _MyHomePageState extends State<MyHomePage> {
int radioValue = 1;
void _handleRadioValueChange(int value) {
setState(() {
radioValue = value;
});
}
void _openDialog() {
DialogFactory.showAlertDialog(
context,
title: Text('Alert Dialog!!!'),
content: Text(
'THIS IS AN ALERT DIALOG! IT MEANS YOU SHOULD BE IN ALERT STATE, RIGHT?'),
actions: [
DialogAction(
child: Text('YES'),
onPressed: () => print('YES'),
),
DialogAction(
child: Text('NO'),
onPressed: () => print('NO'),
)
],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Radio(
value: 0,
groupValue: radioValue,
onChanged: _handleRadioValueChange,
),
new Text('IOS'),
Radio(
value: 1,
groupValue: radioValue,
onChanged: _handleRadioValueChange,
),
new Text('Android'),
RaisedButton(
child: Text('Show Alert'),
color: Colors.purple,
textColor: Colors.white,
onPressed: _openDialog,
),
],
),
),
);
}
}
dialogfactory.dart:
class DialogFactory {
static Future<T> showAlertDialog<T>(BuildContext context,
{Widget title, Widget content, List<DialogAction> actions}) {
IDialog dialogData;
int radioValue = -1;
// HOW TO GET RADIO VALUE?
if (radioValue == 0) {
// ios
dialogData = IosDialog();
} else if (radioValue == 1) {
//android
dialogData = AndroidDialog();
} else {
dialogData = AndroidDialog();
}
return showDialog(
context: context,
builder: (context) => dialogData.create(
context,
title ?? Text('Não informado'),
content ?? Text('Não informado'),
actions ?? [],
),
);
}
}
link to the repository with the code: https://github.com/gicraveiro/FactoryMethod
I passed the radioValue from the homepage.dart into the showAlertDialog.
When i run the program on a device when i tick 2nd or 3rd term it does not take effect.
I am developing an Electronic student attendance tracking system so i decided to use a radio to track the term and also use check box to track the attendance that is checked if the student is present and unchecked if the student is not present but when i check the term radio it gives the correct output on the console but does not take effect on the physical screen.
import 'package:flutter/material.dart';
import 'package:atttendance_register/dataFiles/pupils.dart';
import 'package:atttendance_register/dataFiles/attendance.dart';
import 'package:intl/intl.dart';
class attendance extends StatefulWidget {
static Future<void> show(BuildContext context) async {
await Navigator.of(context).push(
MaterialPageRoute(builder: (context)=>attendance(),fullscreenDialog: true),
);
}
#override
_attendanceState createState() => _attendanceState();
}
class _attendanceState extends State<attendance> {
// final List<Pupils> pupils =[
// Pupils('John', ' Doe', 'Brad', 'Male', '001', DateTime.now(), '21'),
// Pupils('Jane', ' Doe', 'Mary', 'Female', '002', DateTime.now(), '21'),
// Pupils('Mohamed', ' James', '', 'Male', '003', DateTime.now(), '33'),
// Pupils('Titus', ' Nabieu', 'Jusu', 'Male', '004', DateTime.now(), '21'),
// Pupils('Steven', ' kai', 'Rogers', 'Male', '005', DateTime.now(), '21'),
// Pupils('Josephine', ' Bah', 'Neneh', 'Female', '006', DateTime.now(), '23')
//
// ];
final List<Attendance> attendance =[
Attendance(false,'John Doe Brad',DateTime.now(),0),
Attendance(true,'Jane Doe Mary',DateTime.now(),2),
Attendance(false,'Mohamed James',DateTime.now(),1),
Attendance(false,'Titus Nabieu Jusu',DateTime.now(),2),
Attendance(false,'Steven kai Rogers',DateTime.now(),2),
Attendance(false,'Josephine Bah Neneh',DateTime.now(),1)
];
bool selectedCheck = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Enter Attendance'),
backgroundColor: Colors.blue[900],
),
backgroundColor: Colors.blue[100],
body:Container(
child: ListView.builder(
itemCount:attendance.length,
itemBuilder:(BuildContext context, int index){
int selectedRadio = attendance[index].Term;
bool selectedCheck = attendance[index].attendance;
return Container(
child: Card(
child: Column(
//final pupil =pupils[index];
children: <Widget>[
Text(attendance[index].pupilName),
Text('Select Term'),
Row(
children: <Widget>[
Radio(
value:0,
groupValue: selectedRadio,
activeColor: Colors.blue,
onChanged: (T){
print(T);
setState(() {selectedRadio = T;}
);},
),
new Text(
'1st Term'
),
new Radio(
value: 1,
groupValue: selectedRadio,
activeColor: Colors.blue,
onChanged: (T){
print(T);
setState(() {selectedRadio = T;}
);
},
),
new Text(
'2nd Term'
),
new Radio(
value: 2,
groupValue: selectedRadio,
activeColor: Colors.blue,
onChanged: (T){
print(T);
setState(() {selectedRadio = T;}
);
},
),
new Text(
'3rd Term',
),
],
),
Row(
children: <Widget>[
Checkbox(
value: selectedCheck,
activeColor: Colors.blue,
onChanged: (bool value){
print(value);
setState(() {selectedCheck = value;}
);},
),
new Text(
'Present'
),
],
),
],
),
),
);
} ,),
),
);
}
// Widget pupilsCard(BuildContext context, int index){
// final pupil =pupils[index];
// bool selectedRadio = false;
//
// return Container(
// child: Card(
// child: Column(
// children: <Widget>[
// Text(pupil.FirstName+' '+pupil.OtherName+' '+pupil.LastName),
// Text('Select Term'),
// Row(
// children: <Widget>[
//
//
// ],
// ),
// Checkbox(
// value: selectedRadio,
// activeColor: Colors.blue,
// onChanged: (bool value){
// print(value);
// setState(() {selectedRadio = value;}
// );},
// ),
// new Text(
// 'Present'
//
// ),
// ],
// ),
// ),
// );
// }
}
In the onChanged property of your Radio widgets and your Checkbox widget, you are assigning the user selected value to the variable selectedRadio / selectedCheck and here is the problem, because when the new State is created through setState, the ListView is rebuilding and you are reassigning selectedRadio / selectedCheck the old value of the objects in this lines:
int selectedRadio = attendance[index].Term;
bool selectedCheck = attendance[index].attendance;
So you were not changing the actual value of the objects in the List, but you have too:
onChanged: (T) {
print(T);
setState(() => attendance[index].Term = T);
},
and
onChanged: (value) {
print(value);
setState(() => attendance[index].attendance = value);
},