Related
My Dropdown button value doesn't update until the AlertDialog box is closed and reopened.
I have the variable set at the top of my class
class _ItemListState extends State<ItemList> {
int _ratingController;
...
}
Within the class I have an AlertDialog that opens a form, within here I have the DropdownButtonFormField
AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: _eateryController,
autofocus: true,
decoration:
InputDecoration(labelText: 'Eatery', hintText: 'eg Pizza Hut'),
),
TextField(
controller: _supplierController,
decoration: InputDecoration(
labelText: 'Supplier', hintText: 'eg Deliveroo'),
),
TextField(
controller: _descriptionController,
decoration: InputDecoration(
labelText: 'Description', hintText: 'eg cheese pizza'),
),
DropdownButtonFormField<int>(
value: _ratingController,
items: [1, 2, 3, 4, 5]
.map((label) => DropdownMenuItem(
child: Text(label.toString()),
value: label,
))
.toList(),
hint: Text('Rating'),
onChanged: (value) {
setState(() {
_ratingController = value;
});
},
),
],
),
actions: <Widget>[
FlatButton(
onPressed: () {
_handleSubmit(_eateryController.text, _supplierController.text,
_descriptionController.text, _ratingController);
Navigator.pop(context);
},
child: Text('Save'),
),
FlatButton(
onPressed: () => Navigator.pop(context),
child: Text('Cancel'),
)
],
);
the setState doesn't seem to be dynamically updating the fields value. The updated value will only show once I close and re open the AlertDialog.
How can I get this to update instantly?
Thanks
You need to create a new StatefulWidget class that should return your AlertDialog
class MyDialog extends StatefulWidget {
#override
_MyDialogState createState() => _MyDialogState();
}
class _MyDialogState extends State<MyDialog> {
int _ratingController;
#override
Widget build(BuildContext context) {
return AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: _eateryController,
autofocus: true,
decoration:
InputDecoration(labelText: 'Eatery', hintText: 'eg Pizza Hut'),
),
TextField(
controller: _supplierController,
decoration: InputDecoration(
labelText: 'Supplier', hintText: 'eg Deliveroo'),
),
TextField(
controller: _descriptionController,
decoration: InputDecoration(
labelText: 'Description', hintText: 'eg cheese pizza'),
),
DropdownButtonFormField<int>(
value: _ratingController,
items: [1, 2, 3, 4, 5]
.map((label) => DropdownMenuItem(
child: Text(label.toString()),
value: label,
))
.toList(),
hint: Text('Rating'),
onChanged: (value) {
setState(() {
_ratingController = value;
});
},
),
],
),
actions: <Widget>[
FlatButton(
onPressed: () {
_handleSubmit(_eateryController.text, _supplierController.text,
_descriptionController.text, _ratingController);
Navigator.pop(context);
},
child: Text('Save'),
),
FlatButton(
onPressed: () => Navigator.pop(context),
child: Text('Cancel'),
)
],
);
}
}
Use it like this
showDialog(
context: context,
builder: (context) {
return MyDialog();
},
);
You can use statefulBuilder inside alert dialog.
return AlertDialog(
title: new Text('Table'),
content: StatefulBuilder(builder:
(BuildContext context,
StateSetter setState) {
return Container(
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
child: new Column(
children: <Widget>[
DropdownButtonFormField<String>(
value: dropdownValue,
style: TextStyle(
color: Colors.black87),
items: <String>[
'Lot 1',
'Lot 2',
'Lot 3',
'Lot 4',
].map<
DropdownMenuItem<
String>>(
(String value) {
return DropdownMenuItem<
String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
),
```
It looks like you're calling setState in a wrong widget. The AlertDialog doesn't belong to ItemList's tree because it's located inside another Route. So calling setState inside _ItemListState won't rebuild the AlertDialog.
Consider pulling out content of AlertDialog into a separate StatefulWidget and putting int _ratingController into it's state.
I am very new to flutter and stuck on the point of displaying a SnackBar when login fails .Kindly check the code below and let me know how to fix this problem. I don't know where exactly do I need to have builder. You can suggest to me the best solution to display SnackBar in a simple and quick way. Many thanks in advance to all those who will help.
class LoginPage extends StatefulWidget {
static String tag = 'login-page';
#override
_LoginPageState createState() => new _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
bool passwordVisible = true;
var _scaffoldKey = new GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
final logo = Hero(
tag: 'hero',
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 48.0,
child: Image.asset('assets/splash.png'),
),
);
/* final email = TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
initialValue: 'mufeez#gmail.com',
decoration: InputDecoration(
hintText: 'Email',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
),
);
*/
final password = TextFormField(
autofocus: false,
obscureText: passwordVisible,//This will obscure text dynamically
decoration: InputDecoration(
hintText: 'Enter Secret Key',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
suffixIcon: IconButton(
icon: Icon(
// Based on passwordVisible state choose the icon
passwordVisible
? Icons.visibility_off
: Icons.visibility,
color: Theme.of(context).primaryColorDark,
),
onPressed: () {
// Update the state i.e. toogle the state of passwordVisible variable
setState(() {
passwordVisible
? passwordVisible = false
: passwordVisible = true;
});
},
),
),
);
final loginButton = Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
onPressed: () async {
final snackBar = SnackBar(content: Text('Yay! A SnackBar!'));
Scaffold.of(context).showSnackBar(snackBar);
},
padding: EdgeInsets.all(12),
color: Colors.lightBlueAccent,
child: Text('Log In', style: TextStyle(color: Colors.white)),
),
);
/* final forgotLabel = FlatButton(
child: Text(
'Forgot password?',
style: TextStyle(color: Colors.black54),
),
onPressed: () {},
);
*/
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.only(left: 24.0, right: 24.0),
children: <Widget>[
logo,
SizedBox(height: 48.0),
SizedBox(height: 8.0),
password,
SizedBox(height: 24.0),
loginButton,
],
),
),
);
}
you have to use scaffold key to do so.
what you have to add in scaffold widget.
return Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
and at the time of display snackbar you have to use scaffold key.
replace your onPressed with below code.
onPressed: () async {
final snackBar = SnackBar(content: Text('Yay! A SnackBar!'));
_scaffoldKey.currentState.showSnackBar(snackBar);
},
You can also wrap your Scaffold body in a Builder() widget.
return Scaffold(
body: body: Builder(
builder: (BuildContext ctxt) {
return (your content here);}));
and when want to display the Snackbar juste use Scaffold.of(ctxt) onPressed
onPressed: () {
Scaffold.of(ctxt).showSnackBar(
SnackBar(content:Text('My snack')));
},
here in below code i have list of widgets and used in listview iam adding widgets with list.add()in setstate also the list not updating i dont know what's happening . why my list is not updating
Here is below code
class EditorPageState extends State<EditorPage> {
List<Widget> obj = List<Widget>();
GlobalKey formkey= GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
obj.add( TextFormField(
textCapitalization: TextCapitalization.sentences,
maxLength: 50,
decoration: InputDecoration(
labelText: "TITLE",
hintText: "UR ARTICLE NAME"
),
));
obj.add(TextFormField(decoration: InputDecoration(
labelText: "Article's Propic",
hintText: "Only image Url is Accepted"
),));
return Scaffold(
appBar: AppBar(title: Text("data"),),
body: Form(
key: formkey,
child:Stack(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 50),
child: ListView(
shrinkWrap: true,
children: obj
),
),
Container(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(),
Container(
alignment: Alignment.bottomCenter,
height: 50,width: MediaQuery.of(context).size.width,
color: Colors.black38,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.format_bold),color: Colors.white,onPressed: (){
setState(() {
obj.add(TextFormField(
style: TextStyle(fontWeight: FontWeight.bold),
decoration: InputDecoration(
labelText: "heading"
),
));
});
},),
IconButton(icon: Icon(Icons.add),
onPressed: (){
setState(() {
obj.add(TextFormField(
style: TextStyle(fontWeight: FontWeight.bold),
decoration: InputDecoration(
labelText: "Start again here"
),
));
});
}
),
IconButton(icon: Icon(Icons.add_a_photo),
onPressed: (){
}
),
IconButton(icon: Icon(Icons.delete),
onPressed: (){
},
)
],
),
),
],
),
),
],
),
),
);
}
}
the above code is of statefulwidget ad it is fullscreen dialog
thats it can i know why my list is not updated
Well you will need implement a ListViewBuilder to do this and please, split your layout creation your build method isn't readable. I make some changes in your layout to be more readable and the source code has some comments to help you get what I changed. I hope it can help and also you can adapt this code to your needs.
class EditorPageState extends State<EditorPage> {
List<Widget> obj = List<Widget>();
GlobalKey formkey= GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
obj.add( TextFormField(
textCapitalization: TextCapitalization.sentences,
maxLength: 50,
decoration: InputDecoration(
labelText: "TITLE",
hintText: "UR ARTICLE NAME"
),
));
obj.add(TextFormField(decoration: InputDecoration(
labelText: "Article's Propic",
hintText: "Only image Url is Accepted"
),));
return Scaffold(
appBar: AppBar(title: Text("data"),),
//you can use this property to easily create a bottom navigation
bottomNavigationBar: _buildBottomNavigator(), // this method return BottomNavigation layout
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Form(
key: formkey,
/// here your question answer... you need implemet a listView builder
/// in every build this will create a new ListView getting itens of a especific list
child : ListView.builder(
itemCount: obj.length, // number of items in your list
//here the implementation of itemBuilder. take a look at flutter docs to see details
itemBuilder: (BuildContext context, int Itemindex){
return obj[Itemindex]; // return your widget
}),
),
),
);
}
//create your bottom navigation layout
Widget _buildBottomNavigator(){
return Container(
color: Colors.black54,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.format_bold),color: Colors.white,onPressed: (){
setState(() {
obj.add(TextFormField(
style: TextStyle(fontWeight: FontWeight.bold),
decoration: InputDecoration(
labelText: "heading"
),
));
});
},),
IconButton(icon: Icon(Icons.add),
onPressed: (){
print("on pressed");
setState(() {
obj.add( TextFormField(
style: TextStyle(fontWeight: FontWeight.bold),
decoration: InputDecoration(
labelText: "Start again here"
),
));
});
}
),
IconButton(icon: Icon(Icons.add_a_photo),
onPressed: (){
}
),
IconButton(icon: Icon(Icons.delete),
onPressed: (){
},
)
],
),
);
}
I have this simple form, with a textarea and buttons:
When I open the keyboard, I want to decrease the size of the textarea, like a responsive layout. If I close the keyboard, the textarea should fill the remaining screen space available.
desired effect: open / active keyboard
desired effect: closed/no keyboard
My intention is to make the components fill in the screen, regardless device resolution.
Can someone provide a valida example of it? I tried several implementations and I was not able to achive the desired effect.
UPDATE:
My current code for this screen:
new MaterialPageRoute(
builder: (context) {
return new Scaffold(
resizeToAvoidBottomPadding: true,
appBar: new AppBar(
title: new Text('Add new Grocery List'),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.delete),
tooltip: 'Clear Grocery List',
onPressed: () {
this._promptRemoveGroceryBatchList();
},
),
]
),
body: new Container(
padding: const EdgeInsets.all(5.0),
child: new Form(
key: this._formGroceryBatchAdd,
child: new ListView(
children: <Widget>[
new Container(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new TextFormField(
maxLines: 10,
autofocus: true,
decoration: new InputDecoration(
labelText: 'Item List',
hintText: 'Enter a grocery list',
contentPadding: const EdgeInsets.all(16.0)
),
validator: (value) {
if (value.isEmpty) {
return 'Please enter at least one grocery item';
}
},
onSaved: (value) {
this._formBatchGroceryData = value;
},
),
new Padding(
padding: new EdgeInsets.all(8.0),
child: new Text(
'One item per line. Use ":" to specifcy the amount.\n' +
'Example:\n' +
'Potatoes:12\n' +
'Tomatoes:6',
style: new TextStyle(fontSize: 12.0, color: Colors.black54),
),
),
],
),
),
new Container(
child: new ButtonBar(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new RaisedButton(
child: new Text('Add Items'),
color: Theme.of(context).primaryColor,
textColor: Colors.white,
elevation: 4.0,
onPressed: () {
// ACTION GOES HERE
},
),
new RaisedButton(
child: new Text('Cancel'),
onPressed: () {
// ACTION GOES HERE
},
),
]
),
),
]
)
);
)
);
}
)
I'm afraid it can't be directly done using a TextField for the textarea because its size depends on the lines of text you have.
But you can simulate it by surrounding the TextField that allows unlimited lines with a Container.
This is a sample that could work for you:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Flutter Demo Home Page'),
),
body: new Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(),
borderRadius: BorderRadius.circular(4.0),
),
child: Padding(
padding: const EdgeInsets.only(
left: 10.0, bottom: 20.0, right: 10.0),
child: new TextField(
maxLines: null,
decoration: InputDecoration(
border: InputBorder.none,
),
),
),
),
),
),
],
),
);
}
}
I am pretty new to Flutter and Dart and I can't seem to find any hints for this particular topic. I am trying to put 3 RadioListTiles in a Row like so:
Row(
children: [
Expanded(
child:RadioListTile<GoalSelection>(
title: Text(
'Net',
style: Theme.of(context).textTheme.body1,
),
value: GoalSelection.net,
groupValue: _goalSelection,
onChanged: (GoalSelection value) {
setState(() {
_goalSelection = value;
});
},
),
),
Expanded(
child: RadioListTile<GoalSelection>(
title: Text(
'Gross',
style: Theme.of(context).textTheme.body1,
),
value: GoalSelection.gross,
groupValue: _goalSelection,
onChanged: (GoalSelection value) {
setState(() {
_goalSelection = value;
});
},
),
),
Expanded(
child: RadioListTile<GoalSelection>(
title: Text(
'Salary',
style: Theme.of(context).textTheme.body1,
),
value: GoalSelection.salary,
groupValue: _goalSelection,
onChanged: (GoalSelection value) {
setState(() {
_goalSelection = value;
});
},
),
),
],
),
The buttons layout fine, but there seems to be a lot of wasted space for the label. I put a screenshot of what it currently looks like below. I have tried wrapping the Expanded, the RadioListTile, and the Text in Padding widgets (all one at a time) to manually set the padding to 0, but it didn't do anything. I have also tried to change Expanded to Flexible even though I didn't think that would change anything. I am at a loss now. Is there any way to get this layout to work? I am kind of assuming it is something really dumb that I am doing.
You can use Radio + text widget instead of RadioListTile. For removing internal padding in Radio widget set:
Radio(
visualDensity: const VisualDensity(
horizontal: VisualDensity.minimumDensity,
vertical: VisualDensity.minimumDensity),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
.....
),
You can use a Radio and Text widget in a row. But the Radio also has the same padding problem. To remove the padding you can put the Radio as a child of a SizedBox.
eg:- SizedBox(height: 20, width: 20, child: Radio(.......))
RadioListTile is used with the purpose of taking the full width in a vertical scroll list.
If you don't want this behavior, don't use it. Use Radio instead.
just set contentPadding: EdgeInsets.zero
RadioListTile(contentPadding: EdgeInsets.zero)
We can control the padding of the RadioListTile using Flexible widget. As you want to arrange 3 RadioListTiles inside a Row Widget. Please try with the below code, it will work.
Row(
children: <Widget>[
Flexible(
fit: FlexFit.loose,
child:
RadioListTile(
title: const Text('hello'),
onChanged: (value) {
setState(() {});
},
),
),
Flexible(
fit: FlexFit.loose,
child:
RadioListTile(
title: const Text('Lafayette'),
onChanged: (value) {
setState(() {});
},
),
)
],
),
Do, let me know. Once you tried with the above code. If it resolved you problem, please accept my answer as useful and provide your valuable comments.
I got the same problem. You could try to customize with Radio, Text, InkWell, Padding.
class LabeledRadio extends StatelessWidget {
const LabeledRadio({
this.label,
this.padding,
this.groupValue,
this.value,
this.onChanged,
});
final String label;
final EdgeInsets padding;
final bool groupValue;
final bool value;
final Function onChanged;
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
if (value != groupValue)
onChanged(value);
},
child: Padding(
padding: padding,
child: Row(
children: <Widget>[
Radio<bool>(
groupValue: groupValue,
value: value,
onChanged: (bool newValue) {
onChanged(newValue);
},
),
Text(label),
],
),
),
);
}
}
// ...
bool _isRadioSelected = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <LabeledRadio>[
LabeledRadio(
label: 'This is the first label text',
padding: const EdgeInsets.symmetric(horizontal: 5.0),
value: true,
groupValue: _isRadioSelected,
onChanged: (bool newValue) {
setState(() {
_isRadioSelected = newValue;
});
},
),
LabeledRadio(
label: 'This is the second label text',
padding: const EdgeInsets.symmetric(horizontal: 5.0),
value: false,
groupValue: _isRadioSelected,
onChanged: (bool newValue) {
setState(() {
_isRadioSelected = newValue;
});
},
),
],
),
);
}
The documentation: https://api.flutter.dev/flutter/material/RadioListTile-class.html#material.RadioListTile.3
This is how I fix the padding:
enum ContactSex { nam, nu, khac }
class CreateContactScreen extends StatefulWidget {
static const routeName = './create_contact';
#override
_CreateContactScreenState createState() => _CreateContactScreenState();
}
class _CreateContactScreenState extends State<CreateContactScreen> {
ContactSex _contaxtSex = ContactSex.nu;
final _form = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'TẠO LIÊN HỆ',
style: kHeaderTextStyle,
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('XONG', style: TextStyle(color: Colors.white),),
)
],
),
body: Container(
padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 20.0),
child: Form(
key: _form,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'Tên*',
),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
// TODO: when submit this text field
},
validator: (value) {
if (value.isEmpty) {
return 'Hãy nhập tên cho liên hệ.';
}
return null;
},
onSaved: (value) {
// TODO : when save the whole form
},
),
TextFormField(
decoration: InputDecoration(
labelText: 'Họ',
),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
// TODO: when submit this text field
},
// validator: (value) {
// if (value.isEmpty) {
// return null;
// }
// return null;
// },
onSaved: (value) {
// TODO : when save the whole form
},
),
TextFormField(
decoration: InputDecoration(
labelText: 'Số điện thoại*',
),
keyboardType: TextInputType.phone,
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
// TODO: when submit this text field
},
validator: (value) {
if (value.isEmpty) {
return 'Hãy nhập số điện thoại cho liên hệ.';
}
return null;
},
onSaved: (value) {
// TODO : when save the whole form
},
),
TextFormField(
decoration: InputDecoration(
labelText: 'Email',
),
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) {
// TODO: when submit this text field
},
// validator: (value) {
// if (value.isEmpty) {
// return null;
// }
// return null;
// },
onSaved: (value) {
// TODO : when save the whole form
},
),
Container(
padding: EdgeInsets.only(top: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Giới tính',
style: TextStyle(fontSize: 14.0),
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
LabeledRadio(
label: 'Nữ',
padding: EdgeInsets.all(0),
groupValue: _contaxtSex,
value: ContactSex.nu,
onChanged: (ContactSex newValue) {
setState(() {
_contaxtSex = newValue;
});
},
),LabeledRadio(
label: 'Nam',
padding: EdgeInsets.all(0),
groupValue: _contaxtSex,
value: ContactSex.nam,
onChanged: (ContactSex newValue) {
setState(() {
_contaxtSex = newValue;
});
},
),LabeledRadio(
label: 'Khác',
padding: EdgeInsets.all(0),
groupValue: _contaxtSex,
value: ContactSex.khac,
onChanged: (ContactSex newValue) {
setState(() {
_contaxtSex = newValue;
});
},
),
],
),
],
),
)
],
)),
),
),
);
}
}
class LabeledRadio extends StatelessWidget {
final String label;
final EdgeInsets padding;
final ContactSex groupValue;
final ContactSex value;
final Function onChanged;
const LabeledRadio(
{this.label, this.padding, this.groupValue, this.value, this.onChanged});
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
if (value != groupValue) {
onChanged(value);
}
},
child: Padding(
padding: padding,
child: Row(
children: <Widget>[
Radio<ContactSex>(
groupValue: groupValue,
value: value,
onChanged: (ContactSex newValue) {
onChanged(newValue);
},
),
Text(label),
],
),
),
);
}
}
You just need to set the "dense" property to true, example:
RadioListTile<String>(
title: "My radio",
dense: true, // <= here it is !
value: '1',
);
you should achieve this manually like
make a group of Radio() and Text() and wrap with InkWell() for state handling. now remove extra space of radio by materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, That's it. Get idea by sample code.
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
setState(() {
_radioVenue = 0;
});
},
child: Row(
children: [
Radio(
materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap,
activeColor: primaryColor,
groupValue: _radioVenue,
onChanged: (value) {},
value: 0,
),
Text('From our list')
],
),
),
InkWell(
onTap: () {
setState(() {
_radioVenue = 1;
});
},
child: Row(
children: [
Radio(
materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap,
activeColor: primaryColor,
groupValue: _radioVenue,
onChanged: (value) {},
value: 1,
),
Text('From our list')
],
),
),
],
),
We covered both both the issues in this sample.
Removed extra spaces.
whole group is selectable radio + text, Now it behaves like RadioListTile().
Simply use RadioListTile and remove extra padding, by default it's 18
RadioListTile(contentPadding: EdgeInsets.symmetric(horizontal: 0.0)),
OR
RadioListTile(
contentPadding: EdgeInsets.symmetric(horizontal: 0.0),
value: null,
groupValue: null,
onChanged: null,
),
glad to answer
I was looking for same question and ended up on Flutter Documentation
I was working on Column and RadioListTile and I faced same issue, there's a horizontal padding between content inside RadioListTile
So, here it's the answer
Looking for this documentation ! RadioListTile content padding
Just add contentPadding: EdgeInsets.symmetric(horizontal: 0) and here you go, there's no horizontal padding anymore
Just copy paste this code and enjoy
Container(
height:35,
child: Row(
children: [
Radio(
groupValue: data.selected,
value: e,
onChanged: (DataBindModel? value) {
listener.value = MultiChoiceData(selected: value, items: listener.value.items);
onChanged(value);
onSelected(value);
},
),
Text(
e.value,
style: body14,
)
],
),
)
Copy the RadioListTile code and create your on new new file and paste it in there.
Remove the imports causing errors:
import 'package:flutter/widgets.dart'; // leave it
import 'package:flutter/material.dart'; //add
import 'list_tile.dart'; //remove
import 'radio.dart'; //remove
import 'theme.dart'; //remove
import 'theme_data.dart'; //remove
Then add the following padding to it, like this:
//Inside the file locate this widget and Add the padding or remove it. I needed to remove it and add 5.
return MergeSemantics(
child: ListTileTheme.merge(
contentPadding: EdgeInsets.only( // Add this
left: 5,
right: 0,
bottom: 0,
top: 0
),
selectedColor: activeColor ?? Theme.of(context).accentColor,
child: ListTile(
leading: leading,
title: title,
subtitle: subtitle,
trailing: trailing,
isThreeLine: isThreeLine,
dense: dense,
enabled: onChanged != null,
onTap: onChanged != null && !checked ? () { onChanged(value); } : null,
selected: selected,
),
),
);
then Import the file into your project like this:
import 'package:Project_Name/common/customComponets/custom_radio_list_tile.dart' as CustomRadioListTile;
Then use it like this:
CustomRadioListTile.RadioListTile(); // and that's how I managed to do it. Thought I should share.
This is my way of reducing the space. I have three Radio in one row.
Row(
children: [
Expanded(
child: RadioListTile(
contentPadding: EdgeInsets.all(0.0),
value: DayoffType.Range,
groupValue: _dayoffType,
title: Transform.translate(offset: const Offset(-18, 0), child: Text('Range')),
onChanged: (DayoffType? val) {
setState(() {
_dayoffType = val!;
});
},
),
),
Expanded(...Radio2...),
Expanded(...Radio3...)
)