我有一个模态底部表,它有两个单选按钮。但是当按下时,它们不起作用。我不知道问题是什么,我认为这是因为单选按钮位于底部表中。
这是我的代码
import 'package:flutter/material.dart';
class NutritionScreen extends StatefulWidget {
@override
_NutritionScreenState createState() => _NutritionScreenState();
}
class _NutritionScreenState extends State<NutritionScreen> {
double height = 500.0;
TextEditingController textFieldControllerAge = TextEditingController();
TextEditingController textFieldControllerGrowth = TextEditingController();
TextEditingController textFieldControllerWeight = TextEditingController();
TextEditingController textFieldControllerWeightGoal = TextEditingController();
bool _validateAge = false;
bool _validateGrowth = false;
bool _validateWeight = false;
bool _validateWeightGoal = false;
// Declare this variable
int selectedRadioTile;
@override
void initState() {
super.initState();
selectedRadioTile = 0;
}
setSelectedRadioTile(int val) {
setState(() {
selectedRadioTile = val;
});
}
@override
void dispose() {
textFieldControllerAge.dispose();
textFieldControllerGrowth.dispose();
textFieldControllerWeight.dispose();
textFieldControllerWeightGoal.dispose();
super.dispose();
}
void _modalBottomSheetMenu() {
showModalBottomSheet(
context: context,
builder: (builder) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery
.of(context)
.viewInsets
.bottom),
child: new Container(
height: height,
color: Colors
.transparent, //could change this to Color(0xFF737373),
//so you don't have to change MaterialApp canvasColor
child: new Container(
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(10.0),
topRight: const Radius.circular(10.0))),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: EdgeInsets.all(8.0),
child: Text(
"Питание",
textAlign: TextAlign.center,
style:
TextStyle(color: Colors.black, fontSize: 26.0),
)),
Padding(padding: EdgeInsets.all(8.0),
child: TextField(
maxLines: 1,
textDirection: TextDirection.ltr,
controller: textFieldControllerAge,
style: TextStyle(
color: Colors.lightGreen[400],
fontSize: 18.5),
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 4.0),
labelText: "Возраст",
errorText: _validateAge ? 'Поле должно быть заполненным' : null,
alignLabelWithHint: false,
),
keyboardType: TextInputType.phone,
textInputAction: TextInputAction.done,
)),
Padding(padding: EdgeInsets.all(8.0),
child: TextField(
maxLines: 1,
textDirection: TextDirection.ltr,
controller: textFieldControllerGrowth,
style: TextStyle(
color: Colors.lightGreen[400],
fontSize: 18.5),
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 4.0),
labelText: "Рост",
errorText: _validateGrowth ? 'Поле должно быть заполненным' : null,
alignLabelWithHint: false,
),
keyboardType: TextInputType.phone,
textInputAction: TextInputAction.done,
)),
Padding(padding: EdgeInsets.all(8.0),
child: TextField(
maxLines: 1,
textDirection: TextDirection.ltr,
controller: textFieldControllerWeight,
style: TextStyle(
color: Colors.lightGreen[400],
fontSize: 18.5),
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 4.0),
labelText: "Вес",
errorText: _validateWeight ? 'Поле должно быть заполненным' : null,
alignLabelWithHint: false,
),
keyboardType: TextInputType.phone,
textInputAction: TextInputAction.done,
)),
Padding(padding: EdgeInsets.all(8.0),
child: TextField(
maxLines: 1,
textDirection: TextDirection.ltr,
controller: textFieldControllerWeightGoal,
style: TextStyle(
color: Colors.lightGreen[400],
fontSize: 18.5),
decoration: InputDecoration(
contentPadding: EdgeInsets.only(bottom: 4.0),
labelText: "Целевой вес",
errorText: _validateWeightGoal ? 'Поле должно быть заполненным' : null,
alignLabelWithHint: false,
),
keyboardType: TextInputType.phone,
textInputAction: TextInputAction.done,
)),
RadioListTile(
value: 0,
groupValue: selectedRadioTile,
title: Text("Мужчина"),
onChanged: (val) {
setSelectedRadioTile(val);
},
activeColor: Colors.lightGreen[400],
selected: true,
),
RadioListTile(
value: 1,
groupValue: selectedRadioTile,
title: Text("Женщина"),
onChanged: (val) {
setSelectedRadioTile(val);
},
activeColor: Colors.lightGreen[400],
selected: false,
),
Container(
alignment: Alignment.bottomRight,
margin: EdgeInsets.only(top: 30),
child: Padding(
padding: EdgeInsets.all(16.0),
child: FloatingActionButton(
heroTag: "tag4",
backgroundColor: Color(0xffFF7070),
child: Icon(
Icons.check, color: Colors.white),
onPressed: () {
setState(() {
textFieldControllerAge.text.isEmpty ?
_validateAge = true : _validateAge = false;
textFieldControllerGrowth.text.isEmpty ?
_validateGrowth = true : _validateGrowth = false;
textFieldControllerWeight.text.isEmpty ?
_validateWeight = true : _validateWeight = false;
textFieldControllerWeightGoal.text.isEmpty ?
_validateWeightGoal = true : _validateWeightGoal = false;
});
if(textFieldControllerAge.text.isNotEmpty &&
textFieldControllerGrowth.text.isNotEmpty &&
textFieldControllerWeight.text.isNotEmpty &&
textFieldControllerWeightGoal.text.isNotEmpty)
_sendDataToSecondScreen(context);
}))),
],
)),
)),
);
});
}
void _sendDataToSecondScreen(BuildContext context) {
String textAge = textFieldControllerAge.text;
String textGrowth = textFieldControllerGrowth.text;
String textWeight = textFieldControllerWeight.text;
String textWeightGoal = textFieldControllerWeightGoal.text;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
MainNutrition(
textAge: textAge,
textGrowth: textGrowth,
textWeight: textWeight,
textWeightGoal: textWeightGoal),
// Этого класса нет
));
}
@override
Widget build(BuildContext context) {
return new Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Color(0xff2b2b2b),
appBar: AppBar(
backgroundColor: Colors.lightGreen[400],
title: Text(
'Питание',
style: new TextStyle(color: Colors.white),
),
leading: IconButton(
icon: Icon(Icons.arrow_back),
color: Colors.white,
onPressed: () => Navigator.of(context).pop(),
),
),
body: Container(
alignment: Alignment.center,
margin: const EdgeInsets.only(bottom: 45.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 200.0),
child: Text(
"Нажми на кнопку, чтобы добавить правильный рацион питания.",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 20.0),
)),
FloatingActionButton(
heroTag: "tag3",
backgroundColor: Color(0xffFF7070),
child: Icon(Icons.add, color: Colors.white),
onPressed: () {
_modalBottomSheetMenu();
}),
],
),
),
);
}
}
为了更新模态底部工作表中的单选按钮,您需要使用
StatefulBuilder并在按钮处理程序中使用新方法
state(本质上是相同的 setState,只是重命名)所有代码都在这里:
资源
完整的工作示例。由于您没有提供部分代码
(而且我不是 Vanga),我可以假设问题出在其他地方。UPD
问题是它
showModalBottomSheet没有更新它的状态,为了解决这个问题,我建议看这里。实际上,您radio button正在更新它们的值,但由于没有小部件更新,showModalBottomSheet因此不会显示。这可以在视觉上和在 的帮助下看到print("Radio Tile pressed $val");。我还建议将重复的代码移到单独的方法中,这将减少您将来的时间。