英文:
function setState in flutter is not updating variable
问题
以下是您提供的代码的翻译部分:
好的,我有一个页面,根据之前按下的按钮,会显示一组幻灯片。如果这组幻灯片尚未解锁,那么将显示一个带有TextFormField的幻灯片。如果在其中输入代码,它将检查是否在数据库中。我唯一需要的是,当代码不在数据库中时,TextFormField的边框应该变成红色。
问题是,setState()未更新边框条件。我测试过了,变量已更新,但页面没有重建。
以下是代码页面的代码:
class _BreathingSlidesState extends State< BreathingSlides > {
int _currentIndex = 0;
late List< Widget > slideContent;
List< String > premium = ['Inhalation', 'Procedures'];
final _formKey = GlobalKey< FormState > ();
TextEditingController _textFieldController = TextEditingController();
bool ? goodCode;
void updateDoneValue(bool value) {
final breathingWidget = context.findAncestorStateOfType< _BreathingState > ();
if (breathingWidget != null) {
setState(() {
widget.updateDone(value);
});
}
}
void dispose() {
_textFieldController.dispose();
super.dispose();
}
Future< bool > fetchData(String value) async {
List< String > dataList = [];
final querySnapshot = await FirebaseFirestore.instance.collection('uCodes').get();
querySnapshot.docs.forEach((doc) {
var fieldValue = doc.data()['1'].toString();
dataList.add(fieldValue);
});
return dataList.contains(value);
}
@override
void initState() {
super.initState();
if (premium.contains(widget.buttonContext)) {
slideContent = [
Column(
children: [
const Padding(
padding: EdgeInsets.only(top: 80.0, left: 20, right: 20, bottom: 20),
child: Align(alignment: Alignment.center, child: Text("You haven't unlocked this lesson yet", textAlign: TextAlign.center, style: TextStyle(fontSize: 30, color: Colors.black, fontWeight: FontWeight.bold),)),
),
Form(
key: _formKey,
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 60, vertical: 20),
child: Builder(
builder: (context) {
return TextFormField(
controller: _textFieldController,
onFieldSubmitted: (value) async {
_textFieldController.clear();
if (await fetchData(value)) {
goodCode = true;
setState(() {
print("jj");
goodCode = true;
});
} else {
goodCode = false;
setState(() {
print("nn");
goodCode = false; // 如果检测到不良输入,则将标志设置为false
});
print(goodCode);
}
},
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(1),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: goodCode == null ? Colors.grey : Colors.red, // 根据验证结果设置边框颜色
width: 2, // 设置边框宽度
),
),
label: const Center(child: Text("Enter your uCode"), ),
floatingLabelStyle: const TextStyle(color: Color.fromARGB(255, 78, 125, 79), fontSize: 20),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Color.fromARGB(255, 115, 171, 117), width: 4)
)
),
);
}
),
),
]
)
//odkaz do shopu
),
]
)
];
}
}
}
在这里应用了幻灯片:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: const Color.fromARGB(255, 78, 125, 79),
title: const Text('x XP', style: TextStyle(fontSize: 25)),
centerTitle: true
),
body: Column(
children: [
Expanded(
child: PageView.builder(
itemCount: slideContent.length,
itemBuilder: (context, index) {
return Center(
child: slideContent[index],
);
},
onPageChanged: (index) {
setState(() {
_currentIndex = index;
});
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
for (int i = 0; i < slideContent.length; i++)
_buildDot(i == _currentIndex),
],
),
],
),
);
}
希望这能帮助您解决问题。如有其他疑问,请随时提出。
英文:
Okay so I have a page where according to button pressed beforehand a group of slides is shown. If the group of slides is not unlocked yet, instead, one slide with TextFormField will appear. If a code i written into it it will check if its in a database. The only thing I need is, that when the code is not in the database, the border of the TextFormField should turn red.
Problem is, the setState() is not updating the border conditions. I tested it out, the variable is updated, but the page is not rebuilded.
Here's the code of the code page:
class _BreathingSlidesState extends State<BreathingSlides> {
int _currentIndex = 0;
late List<Widget> slideContent;
List<String> premium = ['Inhalation', 'Procedures'];
final _formKey = GlobalKey<FormState>();
TextEditingController _textFieldController = TextEditingController();
bool? goodCode;
void updateDoneValue(bool value) {
final breathingWidget = context.findAncestorStateOfType<_BreathingState>();
if (breathingWidget != null) {
setState(() {
widget.updateDone(value);
});
}
}
void dispose() {
_textFieldController.dispose();
super.dispose();
}
Future<bool> fetchData(String value) async {
List<String> dataList = [];
final querySnapshot = await FirebaseFirestore.instance.collection('uCodes').get();
querySnapshot.docs.forEach((doc) {
var fieldValue = doc.data()['1'].toString();
dataList.add(fieldValue);
});
return dataList.contains(value);
}
@override
void initState() {
super.initState();
if(premium.contains(widget.buttonContext))
{
slideContent = [
Column(
children: [
const Padding(
padding: EdgeInsets.only(top: 80.0, left: 20, right: 20, bottom: 20),
child: Align(alignment: Alignment.center, child: Text("You haven't unlocked this lesson yet",textAlign: TextAlign.center, style: TextStyle(fontSize: 30, color: Colors.black, fontWeight: FontWeight.bold),)),
),
Form(
key: _formKey,
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 60, vertical: 20),
child: Builder(
builder: (context) {
return TextFormField(
controller: _textFieldController,
onFieldSubmitted: (value) async {
_textFieldController.clear();
if (await fetchData(value)) {
goodCode = true;
setState(() {
print("jj");
goodCode = true;
});
}
else{
goodCode = false;
setState(() {
print("nn");
goodCode = false; // Set the flag to false if a bad input is detected
});
print(goodCode);
}
},
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(1),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: goodCode == null ? Colors.grey : Colors.red, // Set border color based on validation result
width: 2, // Set border width
),
),
label: const Center(child: Text("Enter your uCode"),),
floatingLabelStyle: const TextStyle(color: Color.fromARGB(255, 78, 125, 79), fontSize: 20),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Color.fromARGB(255, 115, 171, 117), width: 4)
)
),
);
}
),
),
]
)
//odkaz do shopu
),
])];
}
Here the slides are applied:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: const Color.fromARGB(255, 78, 125, 79),
title: const Text('x XP', style: TextStyle(fontSize: 25)),
centerTitle: true
),
body: Column(
children: [
Expanded(
child: PageView.builder(
itemCount: slideContent.length,
itemBuilder: (context, index) {
return Center(
child: slideContent[index],
);
},
onPageChanged: (index) {
setState(() {
_currentIndex = index;
});
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
for (int i = 0; i < slideContent.length; i++)
_buildDot(i == _currentIndex),
],
),
],
),
);
}
Any ideas are appreciated, thanks a lot.
答案1
得分: 1
好的,对于任何想知道的人,经过一些严格的调试,我发现 setState() 确实被正确调用了,但它没有被更新到 PageView.builder 中的 Center widget。
我找不到如何将变量传递给该小部件,但我了解了 StatefulBuilder()。它仅更新其中的小部件,并对此有所帮助。
我现在在想是否有类似的东西,但没有小部件,只有代码。
编码好运!
英文:
Okay so for anyone wondering, after some hardcore debugging xd i found that setState() is indeed called properly, but it's not updated to the Center widget in PageView.builder.
I couldn't find how to pass the variables to the widget, but i learned about StatefulBuilder(). It updates only the widgets in it, and that helped.
I am now wondering tho if there's something like this, but without widgets, only with code.
Good luck with coding!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论