how can i change a RadioListTile button selection state after it has been initialized in flutter - flutter

I have created a RadioListTile based on a list of string items in an initStat function. But i could not get the radio button to change when it is being selected. If it were in a build function i could just call setState and it would have marked it as selected.
How can i mark it as selected when i have created it at the beginning of the code. below here is the code i have tried, it actually print the selected radioTile value but i could not get it to change the selected state or the radio button selection.
List<String> list = ['Satisfied', 'Not Satisfied', 'Very Satisfied','Neutral'];
String _radioGroupValue = '';
int selectedRadioTile = 0;
void initState() {
super.initState();
selectedRadioTile = 0;
setState(() {
for (int n = 0; n < list.length; n++) {
answersRadio.add(RadioListTile(
value: n,
groupValue: _radioGroupValue,
onChanged: (val) {
print('selected Radio index $val');
setSelectedRadioTile(val);
setState(() {
});
},
title: Text(list[n]),
selected: _radioGroupValue == list[n] ? true : false,
));
}
});
}
setSelectedRadioTile(int val){
setState(() {
selectedRadioTile = val;
});
}
child: Column(children: answersRadio,)

class Example extends StatefulWidget {
const Example({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() {
return _Examplestate();
}
}
class _Examplestate extends State<Example> {
List<String> list = [
'Satisfied',
'Not Satisfied',
'Very Satisfied',
'Neutral'
];
String? _radioGroupValue;
List<RadioListTile> answersRadio = [];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Stateful Widget'),
),
body: Column(
children: [
for (var n in list)
RadioListTile<String>(
value: n,
groupValue: _radioGroupValue,
onChanged: (val) {
_radioGroupValue = val;
setState(() {});
},
title: Text(n),
toggleable: true,
selected: _radioGroupValue == n,
)
],
),
);
}
}

set int _groupValue = -1. define value for value : parameter according your need
Radio(
materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity.comfortable,
activeColor: AppTheme.primaryColor,
value: 1,
groupValue: _groupValue,
onChanged: (value) {
setState(() {
_groupValue = value as int;
});
},
),

Related

How can I only check one checkbox at time?

How can I select/check only one checkbox to be checked at time?
And below is my code
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Checkbox(
checkColor: Colors.white,
value: isChecked,
onChanged: (bool value) {
setState(() {
isChecked = value;
// ignore: unnecessary_statements
passData(certId);
});
},
),
],
)),
Option1 - Using a map to maintain the state
Create a map:
final Map<int, bool> _state = {};
then, check if the value for that index is true/false:
return ListView.builder(itemBuilder: (context, index) {
return CheckboxListTile(
value: _state[index] ?? false,
onChanged: (value) {
setState(() {
_state[index] = value!;
});
},
title: Text(_data[index].text),
);
});
Option 2 - using a model:
class CheckBoxModel {
bool isChecked = false;
String text = "";
CheckBoxModel({required this.isChecked, required this.text});
}
and then, generate a List of 30 widgets:
final _data = List.generate(
30, (index) => CheckBoxModel(isChecked: false, text: "Item $index"));
Now, use a ListView.builder and based on the index, to update the corresponding value:
class Testing extends StatefulWidget {
const Testing({Key? key}) : super(key: key);
#override
State<Testing> createState() => _TestingState();
}
class _TestingState extends State<Testing> {
#override
Widget build(BuildContext context) {
return ListView.builder(itemBuilder: (context, index) {
return CheckboxListTile(
value: _data[index].isChecked,
onChanged: (value) {
setState(() {
_data[index].isChecked = value!;
});
},
title: Text(_data[index].text),
);
});
}
}
See also
Expansion tile trailing icon updates all in list on interaction with one tile. How can I only change the icon for the expanded tile?

How to automatically select all items above the selected one flutter

I have a custom list view with selectable items.And I am trying to select all items automatically present above the one I selected. For Ex: Suppose there is 10 items in the list view and i selected 5th then it should select all the items available above 5th. i.e(1,2,3,4) and when i deselect 3rd item 1,2,3 items should deselected automatically
return CheckboxListTile(
activeColor: const Color.fromARGB(
255, 243, 243, 243),
checkColor: UIGuide.light_Purple,
selectedTileColor:
UIGuide.light_Purple,
value: value.selecteCategorys
.contains(value.feeList[index]
.installmentName ??
'--'),
onChanged: (bool? selected) async {
value.onFeeSelected(
selected!,
value.feeList[index]
.installmentName,
index,
value.feeList[index].netDue);
},
title: Text(
value.feeList[index].netDue ==
null
? '--'
: value.feeList[index].netDue
.toString(),
textAlign: TextAlign.end,
),
secondary: Text(
value.feeList[index]
.installmentName ??
'--',
),
);
do something like this :
1 - get index of selected item
2 - in the callback fun of checkbox do
let say we have list of items named by items
List<Item> items = [];
foo() {
final upperlist = items.getRange(0, index).toList();
upperlist.forEach((item) {item.selected =true });
items.replaceRange(0, index, upperlist);
setState((){});
}
Note, this example isn't perfect, but it's a working example that can get you thinking, as I don't know the bigger picture
Here's my approach:
get the widget and index of the currently selected value using .indexOf()
loop over all the widgets until the previously gotten index
for (var i = 0; i < _data.indexOf(item); i++) {
_data[i].isChecked = value!;
}
Code example
create a class called CheckBoxModel:
class CheckBoxModel {
bool isChecked = false;
String text = "";
CheckBoxModel({required this.isChecked, required this.text});
}
and then, generated 30 widgets:
final _data = List.generate(
30, (index) => CheckBoxModel(isChecked: false, text: "Item $index"));
and used it correspondingly:
Column(
children: [
for (var item in _data)
CheckboxListTile(
value: item.isChecked,
onChanged: (value) {
setState(() {
for (var i = 0; i < _data.indexOf(item); i++) {
_data[i].isChecked = value!;
}
});
},
title: Text(item.text),
),
],
)
Here's a complete runnable snipppet:
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class CheckBoxModel {
bool isChecked = false;
String text = "";
CheckBoxModel({required this.isChecked, required this.text});
}
final _data = List.generate(
30, (index) => CheckBoxModel(isChecked: false, text: "Item $index"));
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Testing(),
),
),
);
}
}
class Testing extends StatefulWidget {
const Testing({Key? key}) : super(key: key);
#override
State<Testing> createState() => _TestingState();
}
class _TestingState extends State<Testing> {
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
for (var item in _data)
CheckboxListTile(
value: item.isChecked,
onChanged: (value) {
setState(() {
for (var i = 0; i < _data.indexOf(item); i++) {
_data[i].isChecked = value!;
}
});
},
title: Text(item.text),
),
],
),
);
}
}

Flutter automatic settings from array

I'm trying to create settings page from json. But first i'm checking if creating is working on static array:
import 'package:flutter/material.dart';
import 'package:settings_ui/settings_ui.dart';
class _SettingsScreenState extends State<SettingsScreen> {
bool lockInBackground = true;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
var tilearray = [{'name':'settings no 1'},{'name':'settings no 2'},{'name':'settings no 3'}];
List<SettingsTile> tiles = [];
log('{$tilearray}');
tiles.add( SettingsTile.switchTile(
initialValue: lockInBackground,
onToggle: (bool value) {
setState(() {
lockInBackground = value;
});
},
leading: Icon(Icons.phonelink_lock),
title: Text('settings no 0')));
tilearray.map((item) => log('test{$item.name}'));
tilearray.map((item) => tiles.add( SettingsTile.switchTile(
initialValue: lockInBackground,
onToggle: (bool value) {
setState(() {
lockInBackground = value;
});
},
leading: Icon(Icons.phonelink_lock),
//title: Text(item['name']!))));
title: Text('debug item'))));
log('{$tiles}');
return Scaffold(
appBar: AppBar(title: Text('Settings UI')),
body: SettingsList(
sections: [
SettingsSection(
title: Text('First Section'),
tiles: tiles,
)
]
)
);
}
}
But the result is only one SettingsTile (Setting no 0)...
The comment I add to check if there's a problem with array item, but no. It looks like tilearray is empty.
It is strange that tilearray.map((item) => log('test{$item.name}')); is empty too
Follow current way.
try putting variable outside the build method or you can use initState
class SettingsScreen extends StatefulWidget {
const SettingsScreen({super.key});
#override
State<SettingsScreen> createState() => _SettingsScreenState();
}
class _SettingsScreenState extends State<SettingsScreen> {
#override
void initState() {
super.initState();
}
Map<String, bool> tilearray = {
'settings no 1': false,
'settings no 2': false,
'settings no 3': false
};
List<SettingsTile> getTiles(BuildContext context) {
List<SettingsTile> tiles = [];
for (int i = 0; i < tilearray.length; i++) {
final question = tilearray.keys.elementAt(i);
final value = tilearray.values.elementAt(i);
tiles.add(SettingsTile.switchTile(
initialValue: value,
onToggle: (bool value) {
setState(() {
tilearray[question] = value;
});
},
leading: Icon(Icons.phonelink_lock),
title: Text(question)));
}
;
return tiles;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Settings UI')),
body: SettingsList(
sections: [
SettingsSection(
title: Text('First Section'),
tiles: getTiles(context),
)
],
),
);
}
}
Got it!
I have to use
for (final item in tilearray){
log('x{$item}');
tiles.add( SettingsTile.switchTile(
initialValue: lockInBackground,
onToggle: (bool value) {
setState(() {
lockInBackground = value;
});
},
leading: Icon(Icons.phonelink_lock),
//title: Text(item['name']!))));
title: Text('element')));
log('{$tiles}');
}
}
instead of
tilearray.map((item) =>
And as #Yeasin Sheikh wrote - have to move it to initState()

Why can't I read data from the shared preferences import?

I have a ListView.builder that builds a certain amount of widgets depending on user input. Each widget has their own specific name and has a DropDownMenu. I save this value with the corresponding name of the widget. It saves it correctly. However, when I try and read the data and create a new list from it, this error appears: [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.
'course' is a list. I am using the shared preferences import. When you tap the flat button, it should build the new list, but it is not. Could you explain to me why this is not working please?
This is code in the main app.
void main() {
runApp(Hemis());
}
class Hemis extends StatefulWidget {
#override
_HemisState createState() => _HemisState();
}
class _HemisState extends State<Hemis> {
_read() async {
final prefs = await SharedPreferences.getInstance();
for(int i = 0; i < course.length; i++) {
listMarks[i].name = course[i].name;
listMarks[i].mark = prefs.getInt(course[i].name) ?? 0;
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
ListView.builder(
itemCount: course.length,
itemBuilder: (context, index) {
return ModuleListItem(
name: '${course[index].name}',
credits: course[index].credits,
);
},
),
FlatButton(
onPressed: () {
_read();
for(int i = 0; i < course.length; i++) {
print('${listMarks[i].name}: ${listMarks[i].mark}');
}
},
),
],
),
)
)
);
}
}
The widget that is being built.
final percentage = List<String>.generate(100, (i) => "$i");
class ModuleListItem extends StatefulWidget {
const ModuleListItem ({ Key key, this.name, this.credits }): super(key: key);
final String name;
final int credits;
#override
_ModuleListItemState createState() => _ModuleListItemState();
}
class _ModuleListItemState extends State<ModuleListItem> {
String dropdownValue;
bool isSwitched = false;
_save() async {
final prefs = await SharedPreferences.getInstance();
final key = '${widget.name}';
final value = int.parse(dropdownValue);
prefs.setInt(key, value);
print('saved $value');
}
#override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
DropdownButton<String>(
value: dropdownValue,
icon: Icon(Icons.keyboard_arrow_down),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
items: percentage.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
),
Switch(
value: isSwitched,
onChanged: (value) {
setState(() {
isSwitched = value;
if(isSwitched == true) {
_save();
}
print(isSwitched);
});
},
),
],
),
);
}
}

Flutter CheckBox

I'm a new Flutter programmer, and I want to know how I can use a CheckBox on my App. The CheckBox doesn't need to return anything, is only a way to the user know the ingredients that they have picked up.
Thanks for everything.
A sample below might help :
bool _afternoonOutdoor = false;
String caption_afternoon_outdoor = 'Afternoon Outdoor';
void _afternoonOutdoorChanged(bool value) => setState(() => _afternoonOutdoor = value);
.
.
.
Widget checkBoxTitleAfternoonOutdoor() {
return Container(
width:230,
child: new CheckboxListTile(
value: _afternoonOutdoor,
onChanged: _afternoonOutdoorChanged,
//title: new Text('Afternoon Outdoor'),
//title: new Text('${_remoteConfig.getString('caption_afternoon_outdoor')}'),
title: new Text(caption_afternoon_outdoor),
controlAffinity: ListTileControlAffinity.leading,
activeColor: Colors.blue));
}
This produces the following result :
import 'package:flutter/material.dart';
import '../Models/meal.dart';
class Checkbox extends StatefulWidget {
#override
_CheckboxState createState() => _CheckboxState();
}
class _CheckboxState extends State<Checkbox> {
bool isCheck = false;
List<Meal> meal;
#override
Widget build(BuildContext context) {
return ListView(
padding: EdgeInsets.all(8.0),
children: meal
.map(
(meal) => CheckboxListTile(
title: Text(meal.ingredientes),
value: isCheck,
onChanged: (val) {
setState(() {
isCheck = val;
});
},
),
)
.toList(),
);
}
}