Is there any callbacks available in flutter for every time the page is visible on screen to reload all the information?
Here is my issue, I am a newbie in flutter and trying to make a trivia game with many categories. So on the home screen, I want to display the overall score (the sum of all score from all categories) with progress Indicator. But, whenever the Home screen is on, the progress indicator is always 0 doesnt show anything unless I Hot reload the app, then you will see it with the current overall score of the quiz.
All I want is to keep Updating the score each time the screen is on..
I used initState() and didChangeDependencies() still not working properly unless the app is Hot reloaded
Here is my code:
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,
),
),
],
),
),
],
),
),
);
}```
CodePudding user response:
Welcome to flutter! I'll first address your problem and suggest a few changes for your code after due to your code being unclear in many places.
(Probably) your problem
mind the setState(() {})
(docs here) method that flutter provides. Whenever you want to change the value of a variable that is being displayed in a class that extends State<T>
, do this change in setState.
So wherever you set progress = generalScore;
, instead use:
setState(() {
progress = generalScore;
});
This makes sure that your screen is actually refreshed and displays the new value.
Style changes
You shouldn't define two generalScore
variables, you have one in your State
and one in your sum
function. Having two makes your code confusing to read.
What really piques my interest though is the entirety of your sum function. This is exactly what for loops can be used for. Instead of:
final double generalScore;
final score1 = (prefs.getInt('counter1') ?? 0);
final score2 = (prefs.getInt('counter2') ?? 0);
...
generalScore = score1.toDouble()
score2.toDouble()
score3.toDouble()
...
Please do something along these lines:
final double generalScore;
for(int i = 1; i <= 20; i ) {
generalScore = prefs.getInt('counter' i) ?? 0;
}
This avoids code duplication and makes your code so much shorter. If you had 200 scores, you wouldn't type them out either, right?
Aside from that, though: Split up the Widgets that you use in build
. I don't know what your app looks like, but having all your widget code in one big build block isn't good practice.
If this doesn't fix your issue, please feel free to comment on this answer. I wish you a lot of success with your project. :)