how to update selected radio button in flutter using getx statemanagment - flutter

I am using Flutter with GetX plugin and I have two radio buttons inside statelessWidget
but the radio button doesn't changed to selected when user click on it
my question is how I can update screen to show selected radio the groupValue attribute changed using GetX pluing.
here is my code
Radio(
value: reportController.period[0],
groupValue: reportController.selectedPeriod,
onChanged: (val) {
reportController.selectedPeriod = val;
},
)
and this is my controller
import 'package:get/get.dart';
import 'package:ycom/models/report.dart';
class ReportController extends GetxController {
var report = Report().obs;
List<String> period = ["evening", "morning"];
void set selectedPeriod(String selectedPeriod) {
report.update((report) {
report.selectedPeriod = selectedPeriod;
});
}
String get selectedPeriod => report.value.selectedPeriod;
}

I solved it by wrapping Radio widget inside Obx() function as following
Obx(() => Radio(
value: reportController.period[0],
groupValue: reportController.selectedPeriod,
onChanged: (val) {
reportController.selectedPeriod = val;
},
))

Here is what I did to achieve this:
My Controller:
class ProfilePageController extends GetxController {
String selectedGender;
final List<String> gender = ["Male", "Female"];
String select;
void onClickRadioButton(value) {
print(value);
select = value;
update();
}
}
My View Code:
Row addRadioButton(int btnIndex, String title) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
GetBuilder<ProfilePageController>(
builder: (_) => Radio(
activeColor: Colors.blue,
value: profilePageController.gender[btnIndex],
groupValue: profilePageController.select,
onChanged: (value) =>
profilePageController.onClickRadioButton(value)),
),
Text(title)
],
);
}
To use, call addRadioButton:
Row(
children: [
addRadioButton(0, "Male"),
addRadioButton(1, "Female"),
],
),

Try {setState(() {reportController.selectedPeriod = val;});} instead {reportController.selectedPeriod = val;},

Related

I want to unselect the radio button after pressing the submit button

I want to unselect the radio button after pressing the submit button .And also I want to validate radio button how I can do that the user must select radio button .
This is my code
int? _selectedValue;
#override
void initState() {
super.initState();
_selectedValue = -1;
}
//radio
///Option A
child: RadioListTile(value: 1, groupValue: _selectedValue,
title: Text(option1controller.text.toString()),
subtitle: Text("Option A"),
activeColor: Colors.green,
onChanged: (value){
setState(() {
_selectedValue=value;
// if (option1controller.text.toString()==null) {
//
// }
});
}
),
),
///Submit button
child: ElevatedButton(onPressed:(){
// _selectedValue=-1;
final id=DateTime.now().microsecondsSinceEpoch.toString();
final ref=FirebaseFirestore.instance.collection("Politics");
if (_formKey.currentState!.validate()) {
ref.doc(id).set({"id":id,"Question":questioncontroller.text,"Option A":option1controller.text,"Option B":option2controller.text,
"Option C":option3controller.text,"Option D":option4controller.text,"Correct":_selectedValue.toString();
questioncontroller.clear();
option1controller.clear();
option3controller.clear();
option2controller.clear();
option4controller.clear();
}
}, child: Text("Submit",style: TextStyle(color: Colors.yellowAccent),)),
),
)
Firstly provide dataType on RadioListTile to nullable int while you are using int? _selectedValue;
RadioListTile<int?>(
Now when you like to reset or have to unselect state , assign null on _selectedValue. You can skip providing default value on initState.
onPressed:(){
setState(() {
_selectedValue = null;

How to disable Dropdownlist once user has selected an item in the Dropdownlist in flutter

My DropdownMenuItem coming from API. How to disable the dropDown once user select a item from the list?
child: DropdownButton<Partner>(
value:
_selectedLab, //USER SELECTED DROPDOWN ITEM VALUE
hint: Text("Select Lab"),
isExpanded: true,
items: data.map((Partner data) =>
DropdownMenuItem<Partner>(
child: Text("${data.partnerName}"),
value: data,
)).toList().cast<DropdownMenuItem<Partner>>(),
onChanged: (val) {
setState(() {
_selectedLab = val!;
encLabId = val.encPartnerId;
getTestByLabResult = getTestByLab();
});
},
),
Create a bool on state bool absoreTap = false; and wrap you DropdownButton with AbsorbPointer like
AbsorbPointer(
absorbing: absoreTap,
child: DropdownButton<Partner>(
value:
_selectedLab, //USER SELECTED DROPDOWN ITEM VALUE
hint: Text("Select Lab"),
isExpanded: true,
items: data.map((Partner data) =>
DropdownMenuItem<Partner>(
child: Text("${data.partnerName}"),
value: data,
)).toList().cast<DropdownMenuItem<Partner>>(),
onChanged: (val) {
setState(() {
_selectedLab = val!;
encLabId = val.encPartnerId;
getTestByLabResult = getTestByLab();
absoreTap = true; ///
});
},
),
You can also check Ignore-pointer here is the different between them

Generating a list of choice chips inside a column

I have an array of strings, which I'm trying to display as choice chips.
I saw the doc of the flutter website (here: https://api.flutter.dev/flutter/material/ChoiceChip-class.html) and I copied it to try and use it in my application.
This is what I have:
Widget categoriesList(BuildContext context) {
return Wrap(
children: [
List<Widget>.generate(
options.length,
(int idx) {
return ChoiceChip(
label: Text(options[idx]),
selected: _value == idx,
onSelected: (bool selected) {
setState(() {
_value = selected ? idx : null;
});
});
},
).toList()
],
);
}
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
Title(),
categoriesList(context),
],
),
);
}
}
The problem is that I always get in categoriesList this error:
The element type 'List<Widget>' can't be assigned to the list type 'Widget'.
I tried to search, and this error seems really common, but I can't really tell what's wrong with the piece of code I have - even after seeing answers that was flagged as correct. And also, this piece of code is from the flutter docs, so I guess it should be fine.
What am I missing?
.toList() automatically generates the List, I can see theres [] in which you parsed the list of widgets.
Simply remove the [], like below:
return Wrap(
children: List<Widget>.generate(
options.length,
(int idx) {
return ChoiceChip(
label: Text(options[idx]),
selected: _value == idx,
onSelected: (bool selected) {
setState(() {
_value = selected ? idx : null;
});
});
},
).toList(),
);

How to get Radio to work on flutter when using dynamic object?

I'm new to flutter and I have issues with Radio.
I got it to work perfectly when using the "regular" method:
int _groupValue=-1;
...
...
child: Align(
alignment: Alignment.center,
child: Column(
children: <Widget>[
RadioListTile(activeColor: Colors.black,
groupValue: _groupValue,
value: 1,
onChanged: (value) { setState(() {
_groupValue=value;
}); },
title: Text("a"),
),
RadioListTile(activeColor: Colors.black,
groupValue: _groupValue,
value: 2,
onChanged: (value) { setState(() {
_groupValue=value;
}); },
title: Text("b"),
),
],
),
),
Since I'm using data from API to create the radio buttons I've changed this code to this:
child: Align(
alignment: Alignment.center,
child: children: radioListView
),
),
and on click of a button i call async method to download the data from the API and like this :
void getApiData() async {
...
...
...
setState() {
var radioListView = List<RadioListTile>();
for (Map<String, dynamic> c in apidata)) {
radioListView.add(new RadioListTile(
groupValue: _groupValue,
value: c['option_value'],
title: c['title'],
onChanged: (value) { setState(() {
_groupValue=value;
});
),
));
}
}
}
using the first code it works but using the second code I just get to see the items but nothing happens when I click on the radio buttons (although the onchanged does trigger because I tried to print the value and it's fine)
what am I doing wrong?
I found the solution here:
https://www.didierboelens.com/2018/05/hint-5-how-to-refresh-the-content-of-a-dialog-via-setstate/
The problem was that I had to seperate the widgets and create another stateful widget for the radio

control & disable a dropdown button in flutter?

I wanted to control a drop-down button and make it unclickable using a button.
Is there any way to make it disable. Basically not allowing it able to change.
new DropdownButton(
value: animalName,
items: animals.map(
(String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text('$value'),
);
},
).toList(),
onChanged: (value) {
setState(() {
animalName = value;
});
},
),
So this is the code I currently use on the drop-down button, but i cant disabled it.
Found this in the DropdownButton docs:
If items or onChanged is null, the button will be disabled, the down arrow will be grayed out, and the disabledHint will be shown (if provided)
DropdownButton(
onChanged: null,
items: [...],
)
This isn't what you want to hear, but I don't think there's currently an easy way. I experimented with simply removing all the items and that causes a nice little crash. Maybe worth raising an issue with the flutter people on github...
There is an alternative that may be good enough for you for now. If you wrap your DropdownButton in an IgnorePointer, when you want it to be disabled you can change IgnorePointer's ignoring property to true.
That way if the user taps on it, it won't do anything.
But you'll probably want to indicate to the user somehow that it's disabled as well, something like setting the hint text (as it's grey).
child: new IgnorePointer(
ignoring: true,
child: new DropdownButton(
hint: new Text("disabled"),
items: ["asdf", "wehee", "asdf2", "qwer"].map(
(String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text('$value'),
);
},
).toList(),
onChanged: (value) {},
),
You can make DropdownButtonFormField or DropdownButton disabled if set onChanged to null, and if you want that dropdown still shows selected value you must set disabledHint. For example:
DropdownButtonFormField<String>(
disabledHint: Text(_selectedItem),
value: _selectedItem,
onChanged: enabled ? (value) => setState(() => _selectedItem = value) : null,
items: items.map<DropdownMenuItem<String>>((item) {
return DropdownMenuItem(
value: item,
child: Text(item),
);
}).toList(),
)
Just wrap it with IgnorePointer widget to make DropdownButton disable
IgnorePointer(
ignoring: enabled,
child: new DropdownButton(
value: animalName,
items: animals.map(
(String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text('$value'),
);
},
).toList(),
onChanged: (value) {
setState(() {
animalName = value;
});
},
),
);
If items or onChanged is null, the button will be disabled, the down
arrow will be grayed out, and the disabledHint will be shown (if
provided)
So something like this should work:
DropdownButton<String>(
...
onChanged: this.enabled ? (id) => setState(() => this.id = id) : null,
)
okay, i found a trick that satisfied me
i wanted it hide/show the DropdownButton depending on CheckboxListTile
in StatefulWidget Class
first create a function ex:
_buildDropDown(bool enable) {
if (enable) {
return DropdownButton<String>(
hint: Text("Hint"),
items: <String>[
'item 1',
'item 2',
'item 3',
].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (value) {},
);
} else { // Just Divider with zero Height xD
return Divider(color: Colors.white, height: 0.0);
}
}
and now in build
bool enable = true;
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
CheckboxListTile(
title: const Text('Switcher'),
selected: true,
value: enable,
onChanged: (bool value) {
setState(() {
enable = value;
});
},
),
_buildDropDown(enable),
],
);
}
now every time you change enable it will display and hide the DropdownButton
DropdownButtonFormField(
onChange: isDisable ? null : (str){
},
disabledHint: isDisable ? null : Text('Your hint text'),
...
)
For disable
onChange: null
For disable Caption
disabledHint: Text('Your hint text')
//add widget'AbsorbPointer' true-disable,false-enable
// isEditable = ture
AbsorbPointer(
absorbing: isEditable
DropdownButton(
onChanged: null,
items: [...],
)
)
Simple:
decoration:InputDecoration(enabled: false),