如何在 flutter 应用程序中通过加载小部件显示黑屏调用时停止 setState?
How to stop setState when called from displaying black screen with loading widget in flutter application?
我正在尝试在我的 Flutter 应用程序中编写一个简单的功能,当用户点击一个对象时它会改变颜色。我使用以下代码执行此操作:
GestureDetector(
onTap: () {
setState(() {
computer = !computer;
});
},
child: SubjectCard(subject: computer, index: 4),
),
class SubjectCard extends StatelessWidget {
var subject;
int index;
SubjectCard({this.subject, this.index});
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: subject == true ? categories[index].color.withOpacity(1) : categories[index].color.withOpacity(0.55),
// color: pressAttention0 == true ? categories[1].color.withOpacity(1) : categories[1].color.withOpacity(0.55),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CircleNumber(index: index + 1),
Container(
width: 60,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey[200],
),
),
),
],
),
Expanded(
child: Container()
),
Text(
categories[index].name,
style: kTitleTextCardStyle,
),
SizedBox(height: 2),
Text(
'${categories[index].numOfTutors} Tutors',
style: TextStyle(
color: Colors.white,
),
),
SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
width: 120,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey[200],
),
),
),
],
),
],
),
);
}
}
我改变颜色的部分是用这行代码:
color: subject == true ? categories[index].color.withOpacity(1) : categories[index].color.withOpacity(0.55),
但是,每当用户单击该对象时,颜色就会发生变化(这是我想要的),但整个应用程序会重新加载,并且用户会立即被发送到带有蓝色大加载指示器的黑屏。我没有对此进行编码,也不确定为什么会这样。屏幕很烦人,我想摆脱它,而是让应用程序在他们不注意的情况下更改对象的颜色。任何帮助将不胜感激。
经过一番挖掘,我发现了为什么会发生这种情况,它可能与您遇到的问题不同,但视觉结果是相同的。我不妨描述一下是什么导致了我的场景中的问题,它与在 statefulWidget 中使用 FutureBuilder 有关。
正在阅读第二段here
The future must have been obtained earlier, e.g. during State.initState, State.didUpdateConfig, or State.didChangeDependencies. It must not be created during the State.build or StatelessWidget.build method call when constructing the FutureBuilder. If the future is created at the same time as the FutureBuilder, then every time the FutureBuilder's parent is rebuilt, the asynchronous task will be restarted.
此处的解决方案是将您的 Future 声明为状态 class 中的字段(变量),并将其设置在 initState
中,而不是直接在构建部分中设置,请参见下面的示例。
class MyWidgetState extends State<MyWidget> {
Future<void> _initializeWidgetFuture;
@override
void initState() {
super.initState();
_initializeWidgetFuture = MyService.GetSomeData(); // Set the future here!!
}
@override
Widget build(BuildContext context) {
return FutureBuilder<void>(
future: _initializeWidgetFuture, // Don't call MyService.GetSomeData() here!!
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return Center(
child: CircularProgressIndicator(),
);
case ConnectionState.active:
case ConnectionState.done:
return Text("Component initalized");
default:
return null;
}
},
);
}
}
我正在尝试在我的 Flutter 应用程序中编写一个简单的功能,当用户点击一个对象时它会改变颜色。我使用以下代码执行此操作:
GestureDetector(
onTap: () {
setState(() {
computer = !computer;
});
},
child: SubjectCard(subject: computer, index: 4),
),
class SubjectCard extends StatelessWidget {
var subject;
int index;
SubjectCard({this.subject, this.index});
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: subject == true ? categories[index].color.withOpacity(1) : categories[index].color.withOpacity(0.55),
// color: pressAttention0 == true ? categories[1].color.withOpacity(1) : categories[1].color.withOpacity(0.55),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CircleNumber(index: index + 1),
Container(
width: 60,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey[200],
),
),
),
],
),
Expanded(
child: Container()
),
Text(
categories[index].name,
style: kTitleTextCardStyle,
),
SizedBox(height: 2),
Text(
'${categories[index].numOfTutors} Tutors',
style: TextStyle(
color: Colors.white,
),
),
SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
width: 120,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey[200],
),
),
),
],
),
],
),
);
}
}
我改变颜色的部分是用这行代码:
color: subject == true ? categories[index].color.withOpacity(1) : categories[index].color.withOpacity(0.55),
但是,每当用户单击该对象时,颜色就会发生变化(这是我想要的),但整个应用程序会重新加载,并且用户会立即被发送到带有蓝色大加载指示器的黑屏。我没有对此进行编码,也不确定为什么会这样。屏幕很烦人,我想摆脱它,而是让应用程序在他们不注意的情况下更改对象的颜色。任何帮助将不胜感激。
经过一番挖掘,我发现了为什么会发生这种情况,它可能与您遇到的问题不同,但视觉结果是相同的。我不妨描述一下是什么导致了我的场景中的问题,它与在 statefulWidget 中使用 FutureBuilder 有关。
正在阅读第二段here
The future must have been obtained earlier, e.g. during State.initState, State.didUpdateConfig, or State.didChangeDependencies. It must not be created during the State.build or StatelessWidget.build method call when constructing the FutureBuilder. If the future is created at the same time as the FutureBuilder, then every time the FutureBuilder's parent is rebuilt, the asynchronous task will be restarted.
此处的解决方案是将您的 Future 声明为状态 class 中的字段(变量),并将其设置在 initState
中,而不是直接在构建部分中设置,请参见下面的示例。
class MyWidgetState extends State<MyWidget> {
Future<void> _initializeWidgetFuture;
@override
void initState() {
super.initState();
_initializeWidgetFuture = MyService.GetSomeData(); // Set the future here!!
}
@override
Widget build(BuildContext context) {
return FutureBuilder<void>(
future: _initializeWidgetFuture, // Don't call MyService.GetSomeData() here!!
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return Center(
child: CircularProgressIndicator(),
);
case ConnectionState.active:
case ConnectionState.done:
return Text("Component initalized");
default:
return null;
}
},
);
}
}