Evertime the setCountDown method is called i get an exception SetStateCalled during build ,,, please help! . I have to display this countdown in a previous screen too , Lets call it screen A and from A i pushReplaced and came to this Charging Screen which displays countdown and uses provider too . But everytime I update the provider value I get an error . It works fine in the debug mode but as soon as build a release it works weirdly . Please help!!!!
import 'dart:async';
import 'dart:developer';
import 'package:chargeapp_master/ChangeNotifiers/ChargeTimeNotifier.dart';
import 'package:chargeapp_master/Screens/main_map_screen.dart';
import 'package:chargeapp_master/Screens/navigation.dart';
import 'package:chargeapp_master/Screens/profile_screens/profile_screen.dart';
import 'package:chargeapp_master/Screens/wallet_screens/wallet_screen.dart';
import 'package:chargeapp_master/assistants/assistant_methods.dart';
import 'package:chargeapp_master/assistants/bluetooth_assistants.dart';
import 'package:chargeapp_master/widgets/bottbar.dart';
import 'package:circular_countdown_timer/circular_countdown_timer.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_fonts/google_fonts.dart';
import '../User Details.dart';
import '../main.dart';
import 'Charging_summary_screen.dart';
import 'package:provider/provider.dart';
class Charging_screen extends StatefulWidget {
int duration;
String amount;
Charging_screen({Key? key, required this.duration, required this.amount})
: super(key: key);
@override
_Charging_screenState createState() => _Charging_screenState();
}
class _Charging_screenState extends State<Charging_screen> with ChangeNotifier {
double h(double height) {
return MediaQuery.of(context).size.height * height;
}
double w(double width) {
return MediaQuery.of(context).size.width * width;
}
void showNotification(String dat) {
flutterLocalNotificationsPlugin.show(
0,
"Powerstrip",
"Charging $dat",
NotificationDetails(
android: AndroidNotificationDetails(channel.id, channel.name,
importance: Importance.high,
color: Colors.blue,
playSound: true,
icon: '@mipmap/ic_launcher')));
}
CountDownController _controller = CountDownController();
Timer? countdownTimer;
Duration myDuration = Duration();
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
Provider.of<ChargeTimeProvider>(context, listen: false)
.setDuration(Duration(minutes: widget.duration));
startTimer();
});
}
void setCountDown() {
final reduceSecondsBy = 1;
var seconds = Provider.of<ChargeTimeProvider>(context, listen: false)
.getDuration()
.inSeconds -
reduceSecondsBy;
log("got seconds from provider " + seconds.toString());
if (seconds < 0) {
countdownTimer?.cancel();
showNotification("Stopped");
log("$charging");
} else {
Provider.of<ChargeTimeProvider>(context, listen: false)
.setDuration(Duration(seconds: seconds));
// myDuration = Duration(seconds: seconds);
}
// setState(() {
// final seconds = myDuration.inSeconds - reduceSecondsBy;
// });
}
void startTimer() {
showNotification("Started");
context.read<ChargeTimeProvider>().setChargeStatus(true);
countdownTimer =
Timer.periodic(Duration(seconds: 1), (_) => setCountDown());
}
void stoptimer() {
Provider.of<ChargeTimeProvider>(context, listen: false)
.setChargeStatus(false);
// context.read<ChargeTimeProvider>().setChargeStatus(false);
log("$charging");
countdownTimer?.cancel();
}
String mins = "";
String sec = "";
var minutesChargedfor;
Future<bool> _onWillPop() async {
return (await showDialog(
barrierDismissible: true,
context: context,
builder: (context) => AlertDialog(
backgroundColor: Colors.black,
title: Text(
'Are you sure?',
style: GoogleFonts.sulphurPoint(color: Colors.white),
),
content: Text(
'Do you want to go to home screen',
style: GoogleFonts.sulphurPoint(color: Colors.white),
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext) => Navigation()));
},
child: const Text('Yes'),
),
],
),
)) ??
false;
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () => _onWillPop(),
child: Scaffold(
backgroundColor: Color(0xff1B1D20),
body: Stack(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 70),
Center(
child: Container(
padding: EdgeInsets.all(12),
// margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(7),
),
child: Text(
"Congratulations, you've added Green miles🍀",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.green.shade600),
),
),
),
const SizedBox(
height: 20,
),
Center(
child: Column(
children: [
Center(
child: CircularCountDownTimer(
duration: widget.duration * 60,
controller: _controller,
width: MediaQuery.of(context).size.width / 2,
height: MediaQuery.of(context).size.height / 2,
ringColor: Colors.grey[400]!,
ringGradient: const LinearGradient(
colors: [Colors.white10, Colors.white70]),
fillColor: Colors.blue,
fillGradient: LinearGradient(colors: [
Colors.blue.shade300,
Colors.blue.shade900
]),
backgroundColor: Colors.grey[500],
backgroundGradient: LinearGradient(colors: [
Colors.grey.shade900,
Colors.grey.shade500
]),
strokeWidth: 20.0,
strokeCap: StrokeCap.round,
textStyle: const TextStyle(
fontSize: 33.0,
color: Colors.white,
fontWeight: FontWeight.bold),
// textFormat: CountdownTextFormat.MM_SS,
isTimerTextShown: true,
isReverse: false,
onComplete: () async {
var secondsChargedfor = widget.duration * 60;
var res = AssistantMethods.stopCharging(
secondsChargedfor, "0");
if (res != "failure") {
await Ble.disconnectDevice(connectedDevice);
stoptimer();
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => Charging_summary(
amount: widget.amount,
duration: widget.duration,
mins: mins,
sec: sec)));
} else {
Fluttertoast.showToast(msg: res);
}
Ble.disconnectDevice(connectedDevice);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => Charging_summary(
amount: widget.amount,
duration: widget.duration,
mins: mins,
sec: sec)));
},
),
),
// SizedBox(height: 10,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(
Icons.flash_on,
size: 30,
color: Colors.blue,
),
SizedBox(
width: 7,
),
Text(
"Charging",
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.w400),
)
],
),
BuildTime(),
],
),
),
const SizedBox(
height: 40,
),
Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Container(
padding: EdgeInsets.all(15),
// height: 130,
// width:MediaQuery.of(context).size.width ,
decoration: const BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.only(
topRight: Radius.circular(10.0),
topLeft: Radius.circular(10.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
user_device_id.toString(),
style: const TextStyle(
fontSize: 14,
color: Colors.white,
fontWeight: FontWeight.w400),
),
],
),
device_type == 0
? Text(
"₹${widget.amount}",
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 18,
color: Colors.white),
)
: const Text(""),
],
),
const SizedBox(
height: 10,
),
Row(
children: [
Expanded(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
primary: Colors.red.shade900,
padding: const EdgeInsets.symmetric(
horizontal: 50, vertical: 15),
// minimumSize: Size(50,20 ),
),
child: const Text(
"Stop",
style: TextStyle(
fontSize: 15, color: Colors.white),
),
onPressed: () async {
var secondsChargedfor = widget.duration * 60;
secondsChargedfor = secondsChargedfor -
(int.parse(mins) * 60 + int.parse(sec));
log(secondsChargedfor.toString());
var res = AssistantMethods.stopCharging(
secondsChargedfor, "1");
if (res != "failure") {
await Ble.startStopTimer(services,
0.toString()); // to stop the charging
_controller.pause();
await Ble.disconnectDevice(connectedDevice);
stoptimer();
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
Charging_summary(
amount: widget.amount,
duration: widget.duration,
mins: mins,
sec: sec)));
} else {
Fluttertoast.showToast(msg: res);
}
},
),
),
],
),
],
),
),
),
],
),
],
),
//bottomNavigationBar: bottbar(),
),
);
}
Widget BuildTime() {
String twoDigits(int n) => n.toString().padLeft(2, '0');
final hours = twoDigits(
context.read<ChargeTimeProvider>().getDuration().inHours.remainder(24));
final minutes = twoDigits(context
.read<ChargeTimeProvider>()
.getDuration()
.inMinutes
.remainder(60));
final seconds = twoDigits(context
.read<ChargeTimeProvider>()
.getDuration()
.inSeconds
.remainder(60));
mins = minutes;
sec = seconds;
Provider.of<ChargeTimeProvider>(context, listen: true)
.setTime("$hours:$minutes:$seconds");
return Consumer<ChargeTimeProvider>(
builder: (context, chargetimenotifier, child) => Text(
"${chargetimenotifier.getTime()} Time Remaining",
style: TextStyle(fontSize: 14, color: Colors.white),
));
}
@override
void dispose() {
super.dispose();
}
}
Add Some Delay
Future.delayed(const Duration(milliseconds: 500), () {
// Here you can write your code
setState(() {
// Here you can write your code for open new view
});
});