每当页面在屏幕上时如何重新加载页面(进度指示器)颤动
How to reload the page whenever the page is on screen (Progress indicator) flutter
每次页面在屏幕上可见时,Flutter 是否提供任何回调以重新加载所有信息?
这是我的问题,我是 flutter 的新手,正在尝试制作一个 问答游戏 有很多类别。所以在主屏幕上,我想用 progress Indicator 显示总分(所有类别的所有分数的总和)。但是,无论何时打开主屏幕,进度指示器总是 0 不显示任何内容,除非我 Hot reload 应用程序,然后你会看到它与当前测验的总分。
我只想在每次屏幕打开时保持更新分数..
我使用了 initState() 和 didChangeDependencies() 仍然无法正常工作,除非应用 热重新加载
这是我的代码:
class Home extends StatefulWidget {
Home({Key? key}) : super(key: key);
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
int? generalScore;
double progress = 0;
//1
void unloadCounter() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('counter1');
}
//2
void unloadCounter2() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('counter2');
}
//3
void unloadCounter3() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('counter3');
}
//4
void unloadCounter4() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('counter4');
}
//5
void unloadCounter5() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('counter5');
}
//Future<double>
void sum() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final double generalScore;
final score1 = (prefs.getInt('counter1') ?? 0);
final score2 = (prefs.getInt('counter2') ?? 0);
final score3 = (prefs.getInt('counter3') ?? 0);
final score4 = (prefs.getInt('counter4') ?? 0);
final score5 = (prefs.getInt('counter5') ?? 0);
final score6 = (prefs.getInt('counter6') ?? 0);
final score7 = (prefs.getInt('counter7') ?? 0);
final score8 = (prefs.getInt('counter8') ?? 0);
final score9 = (prefs.getInt('counter9') ?? 0);
final score10 = (prefs.getInt('counter10') ?? 0);
final score11 = (prefs.getInt('counter11') ?? 0);
final score12 = (prefs.getInt('counter12') ?? 0);
final score13 = (prefs.getInt('counter13') ?? 0);
final score14 = (prefs.getInt('counter14') ?? 0);
final score15 = (prefs.getInt('counter15') ?? 0);
final score16 = (prefs.getInt('counter16') ?? 0);
final score17 = (prefs.getInt('counter17') ?? 0);
final score18 = (prefs.getInt('counter18') ?? 0);
final score19 = (prefs.getInt('counter19') ?? 0);
final score20 = (prefs.getInt('counter20') ?? 0);
generalScore = score1.toDouble() +
score2.toDouble() +
score3.toDouble() +
score4.toDouble() +
score5.toDouble() +
score6.toDouble() +
score7.toDouble() +
score8.toDouble() +
score9.toDouble() +
score10.toDouble() +
score11.toDouble() +
score12.toDouble() +
score13.toDouble() +
score14.toDouble() +
score15.toDouble() +
score16.toDouble() +
score17.toDouble() +
score18.toDouble() +
score19.toDouble() +
score20.toDouble();
progress = generalScore;
// return progress;
}
// @override
// void didUpdateWidget(oldWidget) {
// super.didUpdateWidget(oldWidget);
// //your code for stream
// sum();
// }
@override
void initState() {
// TODO: implement initState
super.initState();
sum();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body:Container(
height: MediaQuery.of(context).size.height * 0.23,
//170,
width: MediaQuery.of(context).size.width,
// color: Colors.blue,
child: Stack(
children: [
Container(
margin: const EdgeInsets.only(
top: 30,
),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.18,
//120,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: AssetImage(
"assets/card.jpg",
),
fit: BoxFit.fill,
),
boxShadow: [
BoxShadow(
blurRadius: 40,
offset: Offset(
8,
10,
),
color: color.AppColor.gradientSecond
.withOpacity(0.3),
),
BoxShadow(
blurRadius: 10,
offset: Offset(
-1,
-5,
),
color: color.AppColor.gradientSecond
.withOpacity(0.3),
),
],
),
),
Container(
height: 100,
//MediaQuery.of(context).size.height * 0.15,
//200
width: MediaQuery.of(context).size.width * 0.25,
margin: const EdgeInsets.only(
left: 250, bottom: 30, top: 50),
decoration: BoxDecoration(
//color: Colors.redAccent.withOpacity(0.2),
borderRadius: BorderRadius.circular(20),
),
child: SizedBox(
height: 90,
width: 90,
//MediaQuery.of(context).size.width * 0.25,
child: Stack(
fit: StackFit.expand,
children: [
CircularProgressIndicator(
value: progress / 200,
valueColor: AlwaysStoppedAnimation(
color.AppColor.homePageDetail),
backgroundColor: Colors.grey,
strokeWidth: 10,
),
Center(
child: progress == 200
? Text(
"MashAllah",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.redAccent),
)
: Text(
"$progress ",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30,
color: Colors.redAccent),
),
// //buildProgress(),
),
],
),
),
),
Container(
width: MediaQuery.of(context).size.width * 0.5,
//double.maxFinite,
height: 100,
//color: Colors.redAccent.withOpacity(0.2),
margin: const EdgeInsets.only(
right: 50, //155,
top: 70,
left: 10,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Score Total:",
style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
color: Colors.black87,
fontFamily: 'KaushanScript',
//color.AppColor.homePageDetail,
),
),
],
),
),
],
),
),
);
}```
欢迎光临!由于您的代码在很多地方都不清楚,我将首先解决您的问题并建议对您的代码进行一些更改。
(可能)你的问题
注意 flutter 提供的 setState(() {})
(docs here) 方法。每当您想更改显示在扩展 State<T>
的 class 中的变量值时, 在 setState 中执行此更改。
所以无论你在哪里设置 progress = generalScore;
,而是使用:
setState(() {
progress = generalScore;
});
这可确保您的屏幕实际刷新并显示新值。
风格改变
您不应该定义两个 generalScore
变量,一个在您的 State
中,一个在您的 sum
函数中。有两个会使您的代码难以阅读。
真正引起我兴趣的是你的总和函数。这正是 for 循环的用途。而不是:
final double generalScore;
final score1 = (prefs.getInt('counter1') ?? 0);
final score2 = (prefs.getInt('counter2') ?? 0);
...
generalScore = score1.toDouble() +
score2.toDouble() +
score3.toDouble() +
...
请按以下方式做一些事情:
final double generalScore;
for(int i = 1; i <= 20; i++) {
generalScore += prefs.getInt('counter' + i) ?? 0;
}
这避免了代码重复并使您的代码更短。如果你有 200 个分数,你也不会打出来,对吧?
但除此之外:拆分您在 build
中使用的小部件。我不知道您的应用程序是什么样子,但是将所有小部件代码放在一个大构建块中并不是一个好习惯。
如果这不能解决您的问题,请随时对此答案发表评论。
祝你的项目取得圆满成功。 :)
每次页面在屏幕上可见时,Flutter 是否提供任何回调以重新加载所有信息?
这是我的问题,我是 flutter 的新手,正在尝试制作一个 问答游戏 有很多类别。所以在主屏幕上,我想用 progress Indicator 显示总分(所有类别的所有分数的总和)。但是,无论何时打开主屏幕,进度指示器总是 0 不显示任何内容,除非我 Hot reload 应用程序,然后你会看到它与当前测验的总分。
我只想在每次屏幕打开时保持更新分数..
我使用了 initState() 和 didChangeDependencies() 仍然无法正常工作,除非应用 热重新加载
这是我的代码:
class Home extends StatefulWidget {
Home({Key? key}) : super(key: key);
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
int? generalScore;
double progress = 0;
//1
void unloadCounter() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('counter1');
}
//2
void unloadCounter2() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('counter2');
}
//3
void unloadCounter3() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('counter3');
}
//4
void unloadCounter4() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('counter4');
}
//5
void unloadCounter5() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('counter5');
}
//Future<double>
void sum() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final double generalScore;
final score1 = (prefs.getInt('counter1') ?? 0);
final score2 = (prefs.getInt('counter2') ?? 0);
final score3 = (prefs.getInt('counter3') ?? 0);
final score4 = (prefs.getInt('counter4') ?? 0);
final score5 = (prefs.getInt('counter5') ?? 0);
final score6 = (prefs.getInt('counter6') ?? 0);
final score7 = (prefs.getInt('counter7') ?? 0);
final score8 = (prefs.getInt('counter8') ?? 0);
final score9 = (prefs.getInt('counter9') ?? 0);
final score10 = (prefs.getInt('counter10') ?? 0);
final score11 = (prefs.getInt('counter11') ?? 0);
final score12 = (prefs.getInt('counter12') ?? 0);
final score13 = (prefs.getInt('counter13') ?? 0);
final score14 = (prefs.getInt('counter14') ?? 0);
final score15 = (prefs.getInt('counter15') ?? 0);
final score16 = (prefs.getInt('counter16') ?? 0);
final score17 = (prefs.getInt('counter17') ?? 0);
final score18 = (prefs.getInt('counter18') ?? 0);
final score19 = (prefs.getInt('counter19') ?? 0);
final score20 = (prefs.getInt('counter20') ?? 0);
generalScore = score1.toDouble() +
score2.toDouble() +
score3.toDouble() +
score4.toDouble() +
score5.toDouble() +
score6.toDouble() +
score7.toDouble() +
score8.toDouble() +
score9.toDouble() +
score10.toDouble() +
score11.toDouble() +
score12.toDouble() +
score13.toDouble() +
score14.toDouble() +
score15.toDouble() +
score16.toDouble() +
score17.toDouble() +
score18.toDouble() +
score19.toDouble() +
score20.toDouble();
progress = generalScore;
// return progress;
}
// @override
// void didUpdateWidget(oldWidget) {
// super.didUpdateWidget(oldWidget);
// //your code for stream
// sum();
// }
@override
void initState() {
// TODO: implement initState
super.initState();
sum();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body:Container(
height: MediaQuery.of(context).size.height * 0.23,
//170,
width: MediaQuery.of(context).size.width,
// color: Colors.blue,
child: Stack(
children: [
Container(
margin: const EdgeInsets.only(
top: 30,
),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.18,
//120,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: AssetImage(
"assets/card.jpg",
),
fit: BoxFit.fill,
),
boxShadow: [
BoxShadow(
blurRadius: 40,
offset: Offset(
8,
10,
),
color: color.AppColor.gradientSecond
.withOpacity(0.3),
),
BoxShadow(
blurRadius: 10,
offset: Offset(
-1,
-5,
),
color: color.AppColor.gradientSecond
.withOpacity(0.3),
),
],
),
),
Container(
height: 100,
//MediaQuery.of(context).size.height * 0.15,
//200
width: MediaQuery.of(context).size.width * 0.25,
margin: const EdgeInsets.only(
left: 250, bottom: 30, top: 50),
decoration: BoxDecoration(
//color: Colors.redAccent.withOpacity(0.2),
borderRadius: BorderRadius.circular(20),
),
child: SizedBox(
height: 90,
width: 90,
//MediaQuery.of(context).size.width * 0.25,
child: Stack(
fit: StackFit.expand,
children: [
CircularProgressIndicator(
value: progress / 200,
valueColor: AlwaysStoppedAnimation(
color.AppColor.homePageDetail),
backgroundColor: Colors.grey,
strokeWidth: 10,
),
Center(
child: progress == 200
? Text(
"MashAllah",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.redAccent),
)
: Text(
"$progress ",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30,
color: Colors.redAccent),
),
// //buildProgress(),
),
],
),
),
),
Container(
width: MediaQuery.of(context).size.width * 0.5,
//double.maxFinite,
height: 100,
//color: Colors.redAccent.withOpacity(0.2),
margin: const EdgeInsets.only(
right: 50, //155,
top: 70,
left: 10,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Score Total:",
style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
color: Colors.black87,
fontFamily: 'KaushanScript',
//color.AppColor.homePageDetail,
),
),
],
),
),
],
),
),
);
}```
欢迎光临!由于您的代码在很多地方都不清楚,我将首先解决您的问题并建议对您的代码进行一些更改。
(可能)你的问题
注意 flutter 提供的 setState(() {})
(docs here) 方法。每当您想更改显示在扩展 State<T>
的 class 中的变量值时, 在 setState 中执行此更改。
所以无论你在哪里设置 progress = generalScore;
,而是使用:
setState(() {
progress = generalScore;
});
这可确保您的屏幕实际刷新并显示新值。
风格改变
您不应该定义两个 generalScore
变量,一个在您的 State
中,一个在您的 sum
函数中。有两个会使您的代码难以阅读。
真正引起我兴趣的是你的总和函数。这正是 for 循环的用途。而不是:
final double generalScore;
final score1 = (prefs.getInt('counter1') ?? 0);
final score2 = (prefs.getInt('counter2') ?? 0);
...
generalScore = score1.toDouble() +
score2.toDouble() +
score3.toDouble() +
...
请按以下方式做一些事情:
final double generalScore;
for(int i = 1; i <= 20; i++) {
generalScore += prefs.getInt('counter' + i) ?? 0;
}
这避免了代码重复并使您的代码更短。如果你有 200 个分数,你也不会打出来,对吧?
但除此之外:拆分您在 build
中使用的小部件。我不知道您的应用程序是什么样子,但是将所有小部件代码放在一个大构建块中并不是一个好习惯。
如果这不能解决您的问题,请随时对此答案发表评论。 祝你的项目取得圆满成功。 :)