单选按钮不会更改 Flutter 中的选择
Posted
技术标签:
【中文标题】单选按钮不会更改 Flutter 中的选择【英文标题】:Radio button not changing the selection in Flutter 【发布时间】:2021-01-02 20:12:32 【问题描述】:我正在创建动态单选按钮并设法显示它。但是,当我点击它时,它不会改变选择。我可以看到 onchanged 事件被触发,我得到了输出,但我认为 SetState 没有按预期工作。
这里是代码。
class FruitsList
String name;
int index;
FruitsList(this.name, this.index);
int _selectedRadioIndex = 1;
// Default Radio Button Item
String radioItem = 'Mango';
// Group Value for Radio Button.
int id = 1;
List<FruitsList> fList = [
FruitsList(
index: 1,
name: "Mango",
),
FruitsList(
index: 2,
name: "Apple",
),
FruitsList(
index: 3,
name: "Banana",
),
FruitsList(
index: 4,
name: "Cheery",
),
];
Column(
children:
fList.map((data) => RadioListTile(
title: Text("$data.name"),
groupValue: id,
value: data.index,
onChanged: (val)
setState(()
radioItem = data.name ;
id = data.index;
print(id);
print(radioItem);
print(val);
_selectedRadioIndex = val;
);
,
)).toList(),
),
我做错了什么?
更新
正如春湖君所建议的那样。
我试过下面的代码。
showDialog(
context: context,
builder: (context)
return StatefulBuilder(
builder: (context, setState)
Column(
children:
fList.map((data) => RadioListTile(
title: Text("$data.name"),
groupValue: id,//_selected,//id,
value: data.index,
onChanged: (val)
setState(()
radioItem = data.name ;
id = data.index;
print(id);
print(radioItem);
print(val);
_selectedRadioIndex = val;
);
,
)).toList(),
);
);
,
);
但它在这些地方给出错误。
showDialog(
context: context,
builder: (context)
'showDialog' must have a method body because '_ApointmentPriceState' isn't abstract.
Try making '_ApointmentPriceState' abstract, or adding a body to 'showDialog'.
【问题讨论】:
您的代码运行良好。如果您在 AlertDialog 中执行此操作。你可以使用StatefulBuilder,看这个***.com/questions/51962272/… 感谢您的评论。所以,我到底需要把这个放在哪里。 return AlertDialog( content: StatefulBuilder( // 你需要这个,注意下面的参数:builder: (BuildContext context, StateSetter setState) 对不起。您的原始代码是否使用 AlertDialog?你能发布你的复制原始代码吗?在我的测试下。它工作正常。所以我猜你在 AlertDialog 中显示数据。如果您的原始代码不使用 AlertDialog,我将需要重现代码。 您可以从这里找到完整的代码。 ***.com/questions/63895921/… 【参考方案1】:您将组值设置为 id
但在 setState 中您正在更改 _selectedRadioIndex
,请像这样更改您的代码:
RadioListTile(
title: Text("$data.name"),
groupValue: _selectedRadioIndex,//_selected,//id,
value: data.index,
onChanged: (val)
setState(()
radioItem = data.name ;
id = data.index;
print(id);
print(radioItem);
print(val);
_selectedRadioIndex = val;
);
【讨论】:
感谢您的回答。我也尝试使用 groupValue: id 和 _selectedRadioIndex。两种方式都行不通。 这应该可以,错误一定在其他地方,您需要发布更多代码。 可以从这个问题***.com/questions/63895921/…看到完整的代码【参考方案2】: import 'package:flutter/material.dart';
void main()
runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
class MyHomePage extends StatefulWidget
MyHomePage(Key key, this.title) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
var _selectedRadioIndex = 1;
@override
Widget build(BuildContext context)
String radioItem = 'Mango';
int id = 1;
List<FruitsList> fList = [
FruitsList(
index: 1,
name: "Mango",
),
FruitsList(
index: 2,
name: "Apple",
),
FruitsList(
index: 3,
name: "Banana",
),
FruitsList(
index: 4,
name: "Cheery",
),
];
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children:
fList.map((data) => RadioListTile(
title: Text("$data.name"),
groupValue: _selectedRadioIndex,
value: data.index,
onChanged: (val)
setState(()
_selectedRadioIndex = val;
radioItem = data.name ;
id = data.index;
print(id);
print(radioItem);
print(val);
);
,
)).toList(),
),
),
);
class FruitsList
String name;
int index;
FruitsList(this.name, this.index);
【讨论】:
让我试试你的解决方案。 我收到了这个错误。没有为类型定义 getter '_selectedRadioIndex'【参考方案3】:您可以在下面复制粘贴运行完整代码
您可以用StatefulBuilder
包裹Row
并使用List<int> _selectedRadioIndexList
和CardNo
来控制
代码sn-p
List<int> _selectedRadioIndexList = [];
int CardNo = -1;
...
_selectedRadioIndexList.add(0);
CardNo = CardNo + 1;
int thisCardNo = CardNo;
...
_selectedRadioIndexList[thisCardNo] = val;
StatefulBuilder(
builder: (BuildContext context, StateSetter setState)
return Row(
children: fList
.map((data) => Container(
width: 100,
child: RadioListTile(
title: Text("$data.name"),
groupValue: id,
value: data.index,
onChanged: (val)
setState(()
radioItem = data.name;
id = data.index;
print(id);
print(radioItem);
print(val);
_selectedRadioIndex = val;
);
,
),
))
.toList(),
);
)
工作演示
完整代码
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
class FruitsList
String name;
int index;
FruitsList(this.name, this.index);
class Price extends StatefulWidget
@override
_PriceState createState() => _PriceState();
class _PriceState extends State<Price>
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _scaffoldKey = GlobalKey<ScaffoldState>();
int currentIndex = 0;
String person;
String age;
String job;
// Default Radio Button Item
String radioItem = 'Mango';
// Group Value for Radio Button.
int id = 1;
//int _selectedRadioIndex = 1;
List<int> _selectedRadioIndexList = [];
List<FruitsList> fList = [
FruitsList(
index: 1,
name: "Mango",
),
FruitsList(
index: 2,
name: "Banana",
),
FruitsList(
index: 3,
name: "Apple",
),
FruitsList(
index: 4,
name: "Cherry",
),
];
int CardNo = -1;
@override
void initState()
super.initState();
cards.add(createCard());
var nameTECs = <TextEditingController>[];
var ageTECs = <TextEditingController>[];
var jobTECs = <TextEditingController>[];
var cards = <Card>[];
Card createCard()
var nameController = TextEditingController();
var ageController = TextEditingController();
var jobController = TextEditingController();
nameTECs.add(nameController);
ageTECs.add(ageController);
jobTECs.add(jobController);
_selectedRadioIndexList.add(0);
CardNo = CardNo + 1;
int thisCardNo = CardNo;
return Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Service $cards.length + 1'),
TextFormField(
style: TextStyle(color: Colors.blue),
controller: nameController,
decoration: InputDecoration(labelText: 'Name'),
validator: validatetext,
onSaved: (String val)
person = val;
,
),
TextFormField(
style: TextStyle(color: Colors.blue),
controller: ageController,
decoration: InputDecoration(labelText: 'age'),
validator: validatetext,
onSaved: (String val)
age = val;
,
),
TextFormField(
style: TextStyle(color: Colors.blue),
controller: jobController,
decoration: InputDecoration(labelText: 'Job'),
validator: validatetext,
onSaved: (String val)
job = val;
,
),
//Expanded(
// child: Container(
// height: 350.0,
// child:
StatefulBuilder(
builder: (BuildContext context, StateSetter setState)
return Row(
children: fList
.map((data) => Container(
width: 100,
child: RadioListTile(
title: Text("$data.name"),
groupValue: id,
value: data.index,
onChanged: (val)
setState(()
radioItem = data.name;
id = data.index;
print(id);
print(radioItem);
print(val);
_selectedRadioIndexList[thisCardNo] = val;
);
,
),
))
.toList(),
);
),
//)),
/* CheckboxListTile(
title: Text("title text"),
value: checkedValue,
onChanged: (newValue)
setState(()
checkedValue = newValue;
);
,
//onChanged: (newValue) ... ,
controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox
), */
SizedBox(height: 10),
],
),
// ),
);
void _validateInputs()
print('button');
if (_formKey.currentState.validate())
_formKey.currentState.save();
_onDone();
else
_onDone()
updateProfile();
List<PersonEntry> entries = [];
for (int i = 0; i < cards.length; i++)
var name = nameTECs[i].text;
var age = ageTECs[i].text;
var job = jobTECs[i].text;
entries.add(PersonEntry(name, age, job));
///////// Save to DB ////////////////////
Future updateProfile() async
try
for (int i = 0; i < cards.length; i++)
var name = nameTECs[i].text;
var age = ageTECs[i].text;
var job = jobTECs[i].text;
Map<String, dynamic> body = 'name': name, 'age': age, 'job': job;
print(body);
nameTECs[i].clear();
//if(rang == true)
Response response = await Dio()
.post("http://192.168.1.102:8080/adddetails.php", data: body);
print(response.statusCode);
if (response.statusCode == 404)
print('404');
if (response.statusCode == 200)
nameTECs[i].clear();
catch (e)
print("Exception Caught: $e");
///////////////////////////////
@override
Widget build(BuildContext context)
return Scaffold(
key: _scaffoldKey,
//appBar: myAppBar(),
//endDrawer: myDrawer(),
body: Column(
children: <Widget>[
Expanded(
child: new Form(
key: _formKey,
child: ListView.builder(
itemCount: cards.length,
itemBuilder: (BuildContext context, int index)
return cards[index];
,
),
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 2.0),
color: Colors.grey,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Container(
Padding(
padding: const EdgeInsets.all(16.0),
child: FloatingActionButton(
heroTag: "btn1",
child: Icon(Icons.add),
onPressed: () => setState(() => cards.add(createCard())),
backgroundColor: Colors.green,
)
/*RaisedButton(
child: Text('Add new'),
onPressed: () => setState(() => cards.add(createCard())),
),*/
),
Padding(
padding: const EdgeInsets.all(16.0),
child: FloatingActionButton(
heroTag: "btn2",
child: Icon(Icons.remove),
onPressed: () => setState(() => cards.removeLast()),
backgroundColor: Colors.red,
)),
Padding(
padding: const EdgeInsets.all(16.0),
child: FloatingActionButton(
heroTag: "btn3",
child: Icon(Icons.save),
onPressed: _validateInputs),
)
],
),
),
],
),
);
class PersonEntry
final String name;
final String age;
final String studyJob;
PersonEntry(this.name, this.age, this.studyJob);
@override
String toString()
return 'Person: name= $name, age= $age, study job= $studyJob';
Size get preferredSize => Size.fromHeight(kToolbarHeight);
String validatetext(String value)
if (value.length < 5)
return 'More than 5 char is required';
else
return null;
void main()
runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Price(),
);
【讨论】:
感谢您的回答。投票赞成。我会仔细阅读并理解为什么它不起作用。我希望当我单击加号按钮时它会起作用,并且不会与卡中现有的收音机冲突。 你可以参考这个medium.com/@Nash0x7E2/…和这个medium.com/flutterdevs/… 感谢您的帮助。我会处理它并尝试检查 http 部分。如果我在 http 请求期间遇到任何问题,我会通知您。 我需要更多帮助。你能告诉我如何在 http 请求中获取单选按钮的选定值。当前代码给出错误。 _selectedradio: final FruitsList = fList.firstWhere((element) => element.index == _selectedRadioIndex);以上是关于单选按钮不会更改 Flutter 中的选择的主要内容,如果未能解决你的问题,请参考以下文章