Im making a study timer app when the startTime and current time have been extracted to two providers using riverpod generator shows state is an int, when I had all of my code on Homepage all of the providers were being set and read correctly everything worked correctly but now when navigating between pages the providers are being reset,
here I am setting them in this class:
//page to set study time before navigating to countdown page
class SetTimer extends ConsumerWidget {
SetTimer({super.key});
//Number input controller
final myController = TextEditingController();
@override
Widget build(BuildContext context, WidgetRef ref) {
//if the timer is null return false else its active using the built in Method
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
TextField(),
Container(
height: 50,
width: 150,
child: TextField(
controller: myController,
decoration: InputDecoration(labelText: "Enter your time"),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
], // Only numbers can be entered
),
),
ElevatedButton(
onPressed: () {
//trying to set the totalDuration now
ref
.read(totalDurationTimerProvider.notifier)
.setTime(int.parse(myController.text));
ref.read(mainTimerProvider.notifier).setTimerTime();
// Navigate to CountDownPage and replace the current route
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
CountDownPage()), // Replace SetTimer with the actual screen you want to navigate to
);
},
child: Text('Set Time'),
),
/*Text(
'closed app: $countValue times',
style: TextStyle(fontSize: 30),
),*/
],
),
),
);
}
}
this is the page being navigated to :
class CountDownPage extends StatelessWidget {
const CountDownPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [BuildTimer(), CustomButton()],
),
),
);
}
}
And this is were I was successfully watching those providers before I added navigation to my app:
class BuildTimer extends ConsumerWidget {
const BuildTimer({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
//seconds will become main timer and maxSeconds will becmoe the user slected time (total_duration)
bool changeColor = false;
int seconds = ref.watch(mainTimerProvider);
int maxSeconds = ref.watch(totalDurationTimerProvider);
return SizedBox(
width: 200,
height: 200,
child: Stack(fit: StackFit.expand, children: [
CircularProgressIndicator(
value: seconds / maxSeconds,
valueColor:
AlwaysStoppedAnimation(changeColor ? Colors.blue : Colors.green),
strokeWidth: 10,
//backgroundColor: Colors.green,
),
Center(child: Text('$seconds', style: TextStyle(fontSize: 50))),
]),
);
}
}
The Issue is the first time I am watching the two providers is inside the build method in BuildTimer and the problem is the widget tree gets refreshed when we navigate from SetTimer, the way to solve this is to watch those two providers for the first time in SetTimer (before the navigation) because a riverpod provider only gets initialized the first time it is watched so I watched them like this in SetTimer simply to allow them to initialize before I shake the widget tree with my navigation:
hope that help, happy coding.