How to hide/show widgets using radio buttons in flutter - flutter

I have a simple app that I am trying to hide or different widgets when a user clicks on yes or no, but when I select Yes or No all the two widgets are shown instead of only showing one when yes is clicked and No when no is clicked and hide Yes or vice versa,
This is what I have done so far
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
// Hide the debug banner
debugShowCheckedModeBanner: false,
title: 'Show Hide Widgets',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// The inital group value
bool visibilityTag = false;
bool visibilityObs = false;
void _changed(bool visibility, String field) {
setState(() {
if (field == "no"){
visibilityTag = visibility;
}
if (field == "yes"){
visibilityObs = visibility;
}
});
}
String _selectedGender = 'None';
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
'Show Hide Widgets',
),
),
body: Padding(
padding: EdgeInsets.all(25),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Please pick one:'),
ListTile(
leading: Radio(
value: 'Yes',
groupValue: _selectedGender,
onChanged: (value) {
setState(() {
_selectedGender = value as String;
visibilityObs ? null : _changed(true, "yes");
});
},
),
title: Text('Yes'),
),
ListTile(
leading: Radio(
value: 'no',
groupValue: _selectedGender,
onChanged: (value) {
setState(() {
_selectedItem = value as String;
visibilityTag ? null : _changed(true, "no");
});
},
),
title: Text('No'),
),
SizedBox(height: 25),
visibilityObs ? new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new Expanded(
flex: 11,
child: new TextField(
maxLines: 1,
style: Theme.of(context).textTheme.headline6,
decoration: new InputDecoration(
labelText: "Yes",
isDense: true
),
),
),
new Expanded(
flex: 1,
child: new IconButton(
color: Colors.grey[400],
icon: const Icon(Icons.cancel, size: 22.0,),
onPressed: () {
_changed(false, "yes");
},
),
),
],
) : new Container(),
visibilityTag ? new Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
new Expanded(
flex: 11,
child: new TextField(
maxLines: 1,
style: Theme.of(context).textTheme.title,
decoration: new InputDecoration(
labelText: "yesno",
isDense: true
),
),
),
new Expanded(
flex: 1,
child: new IconButton(
color: Colors.grey[400],
icon: const Icon(Icons.cancel, size: 22.0,),
onPressed: () {
_changed(false, "no");
},
),
),
],
) : new Container(),
],
)),
);
}
How can I only show the a widget when yes is clicked, and no when no is clicked and Hide the previous yes selected?

From the example in docs:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
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({Key? key}) : super(key: key);
#override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
SingingCharacter? _character = SingingCharacter.lafayette;
#override
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;
});
},
),
),
// -------------------------
_character == SingingCharacter.jefferson
? const ListTile(
title: Text('Something goes here!'),
)
: Container(),
// ----------------------
],
);
}
}

Related

How to bind checkbox form field validator with a button ? (flutter)

How can I bind a checkbox form field validator with a button like in this picture ?
Thank you in advance!
import 'package:flutter/material.dart';
class DummyScreen extends StatefulWidget {
#override
State<DummyScreen> createState() => _DummyScreenState();
}
class _DummyScreenState extends State<DummyScreen> {
bool isSelected = false;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CheckboxListTile(
value: isSelected,
onChanged: (val) {
setState(() {
isSelected = !isSelected;
});
},
title: new Text('I agree.', style: TextStyle(fontSize: 14.0),),
controlAffinity: ListTileControlAffinity.leading,
activeColor: Colors.blue,
),
RaisedButton(
color: isSelected ? Colors.blue : Colors.grey,
child: Text('Button'),
onPressed: () {
if (isSelected) {
///do what you want
}
}
),
],
),
),
);
}
}

A value of type 'Color' can't be assigned to a variable of type 'MaterialColor'

I have an error: A value of type 'Color' can't be assigned to a variable of type 'MaterialColor' in line with code: selectedValue = newValue!.
Please help me solve it. I am attaching the screen code:
class _ColorPickerWidgetState extends State<ColorPickerWidget> {
List<DropdownMenuItem<Color>> get dropdownItems{
List<DropdownMenuItem<Color>> colorItems = [
const DropdownMenuItem(
value: Colors.yellow,
child: Text('Yellow'),
),
const DropdownMenuItem(
value: Colors.red,
child: Text('Red'),
),
];
return colorItems;
}
// default value of select
MaterialColor selectedValue = Colors.yellow;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Choose a color'),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DropdownButton<Color>(
value: selectedValue,
items: dropdownItems,
onChanged: (Color? newValue){
setState(() {
selectedValue = newValue!;
});
},
),
ElevatedButton(onPressed: () => _changeColor(selectedValue),
child: const Text('Next'),
),
],
),
),
);
}
}
Change:
MaterialColor selectedValue = Colors.yellow;
To:
Color selectedValue = Colors.yellow;
While MaterialColor extends ColorSwatch which extends Color, you cannot assign a Color (which might not be a MaterialColor) to MaterialColor
There are 2 two solutions
Maintain only MaterialColor type in all places
class ColorPickerWidget extends StatefulWidget {
const ColorPickerWidget({Key? key}) : super(key: key);
#override
State<ColorPickerWidget> createState() => _ColorPickerWidgetState();
}
class _ColorPickerWidgetState extends State<ColorPickerWidget> {
List<DropdownMenuItem<MaterialColor>> get dropdownItems {
List<DropdownMenuItem<MaterialColor>> colorItems = [
const DropdownMenuItem(
value: Colors.yellow,
child: Text('Yellow'),
),
const DropdownMenuItem(
value: Colors.red,
child: Text('Red'),
),
];
return colorItems;
}
// default value of select
MaterialColor selectedValue = Colors.yellow;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Choose a color'),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DropdownButton<MaterialColor>(
value: selectedValue,
items: dropdownItems,
onChanged: (MaterialColor? newValue) {
setState(() {
selectedValue = newValue!;
});
},
),
ElevatedButton(
onPressed: () => _changeColor(selectedValue),
child: const Text('Next'),
),
],
),
),
);
}
}
Maintain only the Color type in all places
class ColorPickerWidget extends StatefulWidget {
const ColorPickerWidget({Key? key}) : super(key: key);
#override
State<ColorPickerWidget> createState() => _ColorPickerWidgetState();
}
class _ColorPickerWidgetState extends State<ColorPickerWidget> {
List<DropdownMenuItem<Color>> get dropdownItems {
List<DropdownMenuItem<Color>> colorItems = [
const DropdownMenuItem(
value: Colors.yellow,
child: Text('Yellow'),
),
const DropdownMenuItem(
value: Colors.red,
child: Text('Red'),
),
];
return colorItems;
}
// default value of select
Color selectedValue = Colors.yellow;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Choose a color'),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DropdownButton<Color>(
value: selectedValue,
items: dropdownItems,
onChanged: (Color? newValue) {
setState(() {
selectedValue = newValue!;
});
},
),
ElevatedButton(
onPressed: () => _changeColor(selectedValue),
child: const Text('Next'),
),
],
),
),
);
}
}

Why variables in a class not getting changed ? Flutter

I just started learning flutter I needed to pass data between pages so I found it easy to do with static variables but now I'm trying to make a setting page. I made a class named Settings like this :
class Settings {
static bool darkMode = false;
static bool addTable = true;
static saveSetting() {
GetStorage().write("darkMode", Settings.darkMode);
GetStorage().write("addTable", Settings.addTable);
}
static setSetting() {
GetStorage.init();
Settings.darkMode = (GetStorage().read("darkMode") ?? false);
Settings.addTable = (GetStorage().read("addTable") ?? true);
}
}
And a Switch in that page like this :
Switch(
value: Settings.addTable,
onChanged: (_) {
setState(() {
Settings.addTable = !Settings.addTable;
Settings.saveSetting();
});
}),
but after reloading the app the values are not saved in GetStorage, strings are saved perfectly except this one.
And the whole code is here :
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get_storage/get_storage.dart';
import 'widgets/menu_button.dart';
void main() async {
await GetStorage.init();
DataManagament dataManagament = DataManagament();
dataManagament.startingApp();
runApp(const MyApp());
}
class DataManagament {
static String reserveString = "";
static List<String> reserveList = [];
static String tableString = "";
static List<String> tableList = [];
void saveReserveList() {
GetStorage().write("reserveList", reserveList.toString());
}
void saveTableList() {
GetStorage().write("tableList", tableList.toString());
}
void startingApp() {
Settings.setSetting;
//reserve
reserveString = (GetStorage().read("reserveList") ?? "");
reserveString == ""
? reserveList = []
: reserveList =
reserveString.substring(1, reserveString.length - 1).split(",");
//table
tableString = (GetStorage().read("tableList") ?? "");
tableString == ""
? tableList = []
: tableList =
tableString.substring(1, tableString.length - 1).split(",");
}
}
class Settings {
static bool darkMode = false;
static bool addTable = true;
static saveSetting() {
GetStorage().write("darkMode", Settings.darkMode);
GetStorage().write("addTable", Settings.addTable);
}
static setSetting() {
Settings.darkMode = (GetStorage().read("darkMode") ?? false);
Settings.addTable = (GetStorage().read("addTable") ?? true);
}
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: IntroPage(),
debugShowCheckedModeBanner: false,
);
}
}
//
//
//************************************************************
//
//
//
//
//************************************************************
// Reserve Page
//
class ReservePage extends StatefulWidget {
const ReservePage({Key? key}) : super(key: key);
#override
State<ReservePage> createState() => _ReservePageState();
}
class _ReservePageState extends State<ReservePage> {
final _nameController = TextEditingController();
final _minuteController = TextEditingController();
final _hourController = TextEditingController();
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: SingleChildScrollView(
child: Column(
children: [
TextField(
controller: _nameController,
textDirection: TextDirection.rtl,
decoration: const InputDecoration(
hintTextDirection: TextDirection.rtl,
border: OutlineInputBorder(),
labelText: 'نام',
),
),
Row(
children: [
Expanded(
flex: 5,
child: TextField(
controller: _hourController,
maxLength: 2,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'hour',
),
),
),
const Expanded(
flex: 3,
child: Center(
child: Text(
":",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
),
Expanded(
flex: 5,
child: TextField(
controller: _minuteController,
maxLength: 2,
keyboardType: TextInputType.number,
decoration: const InputDecoration(
labelText: 'minute',
),
),
),
],
),
const SizedBox(height: 20),
Center(
child: OutlinedButton(
onPressed: () {
if (_hourController.text != "" &&
_nameController.text != "") {
setState(() {
DataManagament.reserveList
.add(_nameController.text);
DataManagament.reserveList.add(
"${_hourController.text}:${_minuteController.text}");
_hourController.clear();
_nameController.clear();
_minuteController.clear();
DataManagament().saveReserveList();
});
}
},
child: const Text(
"save",
style: TextStyle(
color: Colors.black,
),
),
style: OutlinedButton.styleFrom(
minimumSize: Size(
size.width / 3,
(size.width / 3) * 0.4,
),
backgroundColor: Colors.green,
),
),
)
],
),
),
title: const Center(child: Text("")),
);
});
},
child: const FittedBox(
child: Icon(
Icons.add,
),
),
),
appBar: AppBar(
backgroundColor: Colors.white,
foregroundColor: Colors.black,
title: const Text(
"",
),
centerTitle: true,
),
body: DataManagament.reserveList.isNotEmpty
? SingleChildScrollView(
child: Column(
children: [
ListView.builder(
shrinkWrap: true,
itemCount: DataManagament.reserveList.length ~/ 2,
itemBuilder: (BuildContext context, int index) {
return Card(
// name 0 , time ,1
child: ListTile(
//name
trailing: Text(
DataManagament.reserveList[index * 2],
),
//time
title: Text(
DataManagament.reserveList[(index * 2) + 1],
),
leading: TextButton(
onPressed: () {
setState(() {
DataManagament.reserveList.removeAt(index * 2);
DataManagament.reserveList.removeAt(index * 2);
DataManagament().saveReserveList();
});
},
child: const Text("delete"),
),
));
},
),
],
),
)
: const Center(
child: Text("..."),
),
);
}
}
//
//
//************************************************************
// Menu Page
//
class MenuPage extends StatelessWidget {
const MenuPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SettingsPage(),
));
},
icon: const Icon(Icons.settings),
),
],
backgroundColor: Colors.white,
foregroundColor: Colors.black,
centerTitle: true,
title: const Text(
"",
),
),
body: Column(
children: [
const Spacer(flex: 1),
Expanded(
child: Center(
child: MenuButton(
func: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const TablePage(),
));
},
text: "tables"),
),
flex: 2),
Expanded(
child: Center(
child: MenuButton(
func: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ReservePage(),
));
},
text: "رزروها"),
),
flex: 2),
Expanded(
child: Center(
child: MenuButton(func: () {}, text: "test"),
),
flex: 2),
const Spacer(
flex: 4,
)
],
),
);
}
}
//
//
//************************************************************
// Tables Page
//
class TablePage extends StatefulWidget {
const TablePage({Key? key}) : super(key: key);
#override
State<TablePage> createState() => _TablePageState();
}
class _TablePageState extends State<TablePage> {
final _nameController = TextEditingController(); // ignore: unused_field
final _minuteController = TextEditingController(); // ignore: unused_field
final _hourController = TextEditingController(); // ignore: unused_field
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: Settings.addTable
? GestureDetector(
onLongPress: () {
setState(() {
Settings.addTable = false;
});
},
child: FloatingActionButton(
onPressed: () {
setState(() {
});
},
child: const Icon(
Icons.add,
),
),
)
: null,
appBar: AppBar(
backgroundColor: Colors.white,
foregroundColor: Colors.black,
title: const Text(
"tables",
),
centerTitle: true,
),
body: DataManagament.tableList.isNotEmpty
? SingleChildScrollView(
child: Column(
children: [
ListView.builder(
shrinkWrap: true,
itemCount: DataManagament.tableList.length,
itemBuilder: (BuildContext context, int index) {
return Card(
// name 0 , time ,1
child: ListTile(
//name
trailing: Row(
children: [
Text(index.toString()),
TextButton(
onPressed: () {
setState(() {
DataManagament.tableList[index] =
_nameController.text;
});
},
child: const Text(""),
),
],
),
//time
title: TextButton(
onPressed: () {},
child: const Text(""),
),
leading: TextButton(
onPressed: () {},
child: Text(
DataManagament.tableList[index].toString()),
),
),
);
},
),
],
),
)
: const Center(
child: Text("..."),
),
);
}
}
//
//
//************************************************************
// Intro Page
//
class IntroPage extends StatefulWidget {
const IntroPage({Key? key}) : super(key: key);
#override
State<IntroPage> createState() => _IntroPageState();
}
class _IntroPageState extends State<IntroPage> {
Timer? _timer;
void startTimer() {
_timer = Timer(const Duration(seconds: 3), () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const MenuPage(),
));
});
}
#override
void initState() {
super.initState();
startTimer();
}
#override
void dispose() {
_timer!.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
child: Center(
child: Image.asset("images/eightball.png"),
),
flex: 4),
const Expanded(
child: Center(
child: CircularProgressIndicator(),
),
),
],
),
);
}
}
//
//
//************************************************************
// Settings Page
//
class SettingsPage extends StatefulWidget {
const SettingsPage({Key? key}) : super(key: key);
#override
State<SettingsPage> createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
foregroundColor: Colors.black,
title: const Text("settings"),
),
body: ListView(children: [
Card(
child: ListTile(
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: const [
Text(
"add table",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(width: 10),
Icon(Icons.add, size: 30),
],
),
leading: Switch(
value: Settings.addTable,
onChanged: (_) {
setState(() {
Settings.addTable = !Settings.addTable;
Settings.saveSetting();
});
}),
),
),
Card(
child: ListTile(
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: const [
Text(
"night mode",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(width: 20),
Icon(Icons.dark_mode),
],
),
leading: Switch(
value: Settings.darkMode,
onChanged: (_) {
setState(() {
Settings.darkMode = !Settings.darkMode;
Settings.saveSetting();
});
}),
),
),
]),
);
}
}
You need to call
final settings = new Settings();
settings.setSettings();
in a page where you want to access settings
I think you are just reading data from GetStorage inside setSettings instead of writing to storage, so when the app releods or restarts data inside static variables will not be available. as:
static setSetting() {
GetStorage.init();
Settings.darkMode = (GetStorage().read("darkMode") ?? false);
Settings.addTable = (GetStorage().read("addTable") ?? true);
//Here you are just updating your settings variable.
//Update you storage also to keep the selection in storage
}
Hope it works.

flutter validate radio buttons

How can I add a validator function to a list of RadioButtons in order to have them validated (like TextFormFields with _formKey.currentState.validate()) after the User submits the Form?
You can copy paste run full code below
You can use package https://pub.dev/packages/flutter_form_builder
It support bulid-in validators such as FormBuilderValidators.required() you can directly use
you can also use custom validator function https://pub.dev/packages/flutter_form_builder#custom-validator-function
FormBuilderRadio(
decoration:
InputDecoration(labelText: 'My chosen language'),
attribute: "best_language",
leadingInput: true,
onChanged: _onChanged,
validators: [FormBuilderValidators.required()],
options:
["Dart", "Kotlin", "Java", "Swift", "Objective-C"]
.map((lang) => FormBuilderFieldOption(
value: lang,
child: Text('$lang'),
))
.toList(growable: false),
),
working demo
full code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter FormBuilder Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
inputDecorationTheme: InputDecorationTheme(
labelStyle: TextStyle(color: Colors.purple),
),
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
MyHomePageState createState() {
return MyHomePageState();
}
}
class MyHomePageState extends State<MyHomePage> {
var data;
bool autoValidate = true;
bool readOnly = false;
bool showSegmentedControl = true;
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
final GlobalKey<FormFieldState> _specifyTextFieldKey =
GlobalKey<FormFieldState>();
ValueChanged _onChanged = (val) => print(val);
var genderOptions = ['Male', 'Female', 'Other'];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("FormBuilder Example"),
),
body: Padding(
padding: EdgeInsets.all(10),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
FormBuilder(
// context,
key: _fbKey,
autovalidate: true,
initialValue: {
'movie_rating': 5,
},
readOnly: false,
child: Column(
children: <Widget>[
FormBuilderRadio(
decoration:
InputDecoration(labelText: 'My chosen language'),
attribute: "best_language",
leadingInput: true,
onChanged: _onChanged,
validators: [FormBuilderValidators.required()],
options:
["Dart", "Kotlin", "Java", "Swift", "Objective-C"]
.map((lang) => FormBuilderFieldOption(
value: lang,
child: Text('$lang'),
))
.toList(growable: false),
),
],
),
),
Row(
children: <Widget>[
Expanded(
child: MaterialButton(
color: Theme.of(context).accentColor,
child: Text(
"Submit",
style: TextStyle(color: Colors.white),
),
onPressed: () {
if (_fbKey.currentState.saveAndValidate()) {
print(_fbKey.currentState.value);
} else {
print(_fbKey.currentState.value);
print("validation failed");
}
},
),
),
SizedBox(
width: 20,
),
Expanded(
child: MaterialButton(
color: Theme.of(context).accentColor,
child: Text(
"Reset",
style: TextStyle(color: Colors.white),
),
onPressed: () {
_fbKey.currentState.reset();
},
),
),
],
),
],
),
),
),
);
}
}

ListTile does not show radio buttons in horizontal way in the subtitle

I want to display 2 radio buttons horizontally on the subtitle of the ListTile.
I can see only one Radio Button.
List<QuestionsOptions> optionsList = [
QuestionsOptions(
index: 1,
name: "Yes",
),
QuestionsOptions(
index: 0,
name: "No",
),
];
subtitle:Column(
children: [
new Row(
children: <Widget>[
Expanded(
child: Container(
child: Column(
children:
optionsList.map((data) => RadioListTile(
title: Text("${data.name}"),
groupValue: 0,
value: data.index,
onChanged: (val) {
//_handleWeightChange(data.name,data.index);
},
)).toList(),
),
)),
],
),
]),
How to display both the radio buttons in horizontal in the subtitle of the Listtile
You can set a Row of RadioListTile in the subTitle of the ListTile. You can then use HashMap to track the selected RadioListTile on the List items. The map can be updated when the radio button is clicked. Or if you're using a List for your ListTiles, you can just add the Answer enum on the Object.
subtitle: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Row(
children: [
Expanded(
child: RadioListTile<Answer>(
title: const Text('Yes'),
value: Answer.yes,
groupValue: answerVal[index],
onChanged: (Answer? value) {
setState(() {
// Update map value on tap
answerVal[index] = value;
});
},
),
),
Expanded(
child: RadioListTile<Answer>(
title: const Text('No'),
value: Answer.no,
groupValue: answerVal[index],
onChanged: (Answer? value) {
setState(() {
answerVal[index] = value;
});
},
),
),
],
),
),
Here's the complete sample
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
enum Answer { yes, no }
class _MyHomePageState extends State<MyHomePage> {
Map<int, Answer?> answerVal = {};
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView.builder(
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return ListTile(
contentPadding: const EdgeInsets.all(16.0),
title: const Text('Question?'),
subtitle: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Row(
children: [
Expanded(
child: RadioListTile<Answer>(
title: const Text('Yes'),
value: Answer.yes,
groupValue: answerVal[index],
onChanged: (Answer? value) {
setState(() {
answerVal[index] = value;
});
},
),
),
Expanded(
child: RadioListTile<Answer>(
title: const Text('No'),
value: Answer.no,
groupValue: answerVal[index],
onChanged: (Answer? value) {
setState(() {
answerVal[index] = value;
});
},
),
),
],
),
),
);
},
),
);
}
}