我有以下代码,可以在颤动的屏幕中创建年龄输入字段。当用户尝试进入下一个屏幕而不输入任何内容时,我想向用户显示一个祝酒词。我可以打印出我想要在吐司中显示的内容,但由于某种原因,scaffold.showSnackBar 函数不适合我。有人可以帮我解决这个问题吗?这是代码:
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:workout_app/Screens/Components/Sign_Up_Screens/screen1.dart';
import 'package:workout_app/Screens/Components/Sign_Up_Screens/screen3.dart';
class screen2 extends StatefulWidget {
@override
State<StatefulWidget> createState() => Main();
}
class Main extends State<screen2> {
void returnScreen(context) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
fullscreenDialog: true,
builder: (context) => screen1(),
),
);
}
@override
void initState() {
loadData();
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
int age = 10;
bool nextValid = false;
void toast(String text) {
print(text);
final scaffold = ScaffoldMessenger.of(context);
scaffold.showSnackBar(
SnackBar(
content: Text(text),
),
);
}
void submitData() async {
if(nextValid == false) {
toast('Please input your age');
return;
}
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setInt('age', age);
Navigator.of(context).pushReplacement(
MaterialPageRoute(
fullscreenDialog: true,
builder: (context) => SingleSelectListViewWithLogo(items : ['Tone Up - You want visible muscles with as little mass as possible and a low body fat percentage', 'Bulk Up - You want large, defined muscles, with a low percentage of body fat', 'Get Jacked - You want to lift an insane amount of weight and don\'t care about body fat or muscle definition']),
),
);
}
void loadData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
try {
int? x = prefs.getInt('age');
print(x);
if(x != null) {
setState(() => {age = x});
}
} catch (Exception){
//continue;
}
}
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Material(
child: Container (
decoration: const BoxDecoration(color: Colors.grey),
height: size.height,
width: double.infinity,
child: Stack(
children: <Widget> [
Positioned(
top: size.height * .06,
left: size.width * .03,
child: InkWell(
onTap: () {
returnScreen(context);
},
child: Image.asset(
alignment: Alignment.topLeft,
"assets/images/back2.png",
width: size.width * .07,
),
),
),
Positioned(
top: size.height * .09,
left: size.width * .42,
child: const Text(
style: TextStyle(fontSize: 30, color: Color.fromARGB(255, 4, 3, 3)),
'Next,'
)
),
Positioned(
top: size.height * .15,
left: size.width * .16,
child: const Text(
style: TextStyle(fontSize: 20, color: Color.fromARGB(255, 76, 74, 74)),
'Lets customize your workout!'
)
),
Positioned (
top: size.height * .23,
left: size.width * .28,
child: Image.asset(
"assets/images/age.png",
width: size.width * .4
)
),
Positioned(
top: size.height * .55,
left: size.width * .15,
child: const Text(
style: TextStyle(fontSize: 25, color: Color.fromARGB(255, 21, 17, 17)),
'What\'s your current age?'
)
),
Positioned (
top: size.height * .7,
left: size.width * .1,
child: SliderTheme(
data: const SliderThemeData(
trackHeight: 30,
inactiveTrackColor: Color.fromARGB(255, 255, 255, 255),
activeTrackColor: Color.fromARGB(255, 50, 45, 45),
thumbColor: Colors.black,
disabledActiveTrackColor: Colors.black,
disabledInactiveTrackColor: Colors.black12,
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 25.0),
),
child: Container (
width: size.width * .8,
child: Slider(
label: "Select Age",
value: age.toDouble(),
onChanged: (value) {
setState(() {
age = value.toInt();
nextValid = true;
});
},
min: 10,
max: 99,
)
)
)
),
Positioned (
top: size.height * .62,
left: size.width * .28,
child: Text(
age.toString(),
style: const TextStyle(
fontSize: 40.0,
),
),
),
Positioned (
top: size.height * .64,
left: size.width * .42,
child: const Text (
'years old',
style: TextStyle(
fontSize: 25.0,
),
)
),
Positioned(
top: size.height * .86,
left: size.width * .1,
child: SizedBox(
width: size.width * .8,
height: size.height * .08,
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(!nextValid ? Color.fromRGBO(69, 75, 85, 1) : Color.fromARGB(255, 0, 147, 246)),
),
child: const Text('Continue',
style: TextStyle(fontSize: 20),
),
onPressed: () async {
submitData();
},
),
),
),
]
)
)
);
}
}
让我们一起深入研究这个问题,我想先向您展示问题,然后再展示解决方案。
问题: 您试图在没有
SnackBar
小部件作为父级的情况下将 Scaffold
弹出到屏幕中。打印到调试控制台的问题:
ScaffoldMessenger.showSnackBar was called, but there are currently no descendant Scaffolds to present to.
此消息告诉我们,当所有
Scaffold
的列表为空时,不可能将 Snackbar
弹出到屏幕上。
解决方案:用
Scaffold
包裹孩子,以显示SnackBar
。
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return Material(
//Wrap the children with a Scaffold in order to use ScaffoldMessenger
child: Scaffold(
body: Container(
decoration: const BoxDecoration(color: Colors.grey),
height: size.height,
width: double.infinity,
child: Stack(
children: <Widget>[
Positioned(
top: size.height * .06,
left: size.width * .03,
child: InkWell(
onTap: () {
returnScreen(context);
},
child: Image.asset(
alignment: Alignment.topLeft,
"assets/images/back2.png",
width: size.width * .07,
),
),
),
Positioned(
top: size.height * .09,
left: size.width * .42,
child: const Text(
style: TextStyle(
fontSize: 30, color: Color.fromARGB(255, 4, 3, 3)),
'Next,')),
Positioned(
top: size.height * .15,
left: size.width * .16,
child: const Text(
style: TextStyle(
fontSize: 20, color: Color.fromARGB(255, 76, 74, 74)),
'Lets customize your workout!')),
Positioned(
top: size.height * .23,
left: size.width * .28,
child: Image.asset("assets/images/age.png",
width: size.width * .4)),
Positioned(
top: size.height * .55,
left: size.width * .15,
child: const Text(
style: TextStyle(
fontSize: 25, color: Color.fromARGB(255, 21, 17, 17)),
'What\'s your current age?')),
Positioned(
top: size.height * .7,
left: size.width * .1,
child: SliderTheme(
data: const SliderThemeData(
trackHeight: 30,
inactiveTrackColor: Color.fromARGB(255, 255, 255, 255),
activeTrackColor: Color.fromARGB(255, 50, 45, 45),
thumbColor: Colors.black,
disabledActiveTrackColor: Colors.black,
disabledInactiveTrackColor: Colors.black12,
thumbShape:
RoundSliderThumbShape(enabledThumbRadius: 25.0),
),
child: SizedBox(
width: size.width * .8,
child: Slider(
label: "Select Age",
value: age.toDouble(),
onChanged: (value) {
setState(() {
age = value.toInt();
nextValid = true;
});
},
min: 10,
max: 99,
)))),
Positioned(
top: size.height * .62,
left: size.width * .28,
child: Text(
age.toString(),
style: const TextStyle(
fontSize: 40.0,
),
),
),
Positioned(
top: size.height * .64,
left: size.width * .42,
child: const Text(
'years old',
style: TextStyle(
fontSize: 25.0,
),
)),
Positioned(
top: size.height * .86,
left: size.width * .1,
child: SizedBox(
width: size.width * .8,
height: size.height * .08,
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
!nextValid
? const Color.fromRGBO(69, 75, 85, 1)
: const Color.fromARGB(255, 0, 147, 246)),
),
child: const Text(
'Continue',
style: TextStyle(fontSize: 20),
),
onPressed: () async {
submitData();
},
),
),
),
],
),
),
),
);
}
编辑:我强烈建议您查看 Flutter 烹饪书,那里显示小吃栏和其他有用的东西:)。
您应该按照 flutter 官方文档的要求将材质小部件中的第一个小部件包装在支架内。
您可以在这里阅读更多相关信息