I have a video playing till the wanted duration (Timer). When the timer is done, it will navigate to another screen. Also, I have a skip button if the user wanted to skip the video to go to the next screen. Here is the problem, if the user clicks the skip button, the timer is still running and the screen will be updated even the user skipped the video. I want the timer to stop when the user chooses to skip.
The code:
//imports
class _VideoAppState extends State<additionVideo> {
late VideoPlayerController _controller; //the controller of the video player
@override
void initState() {
super.initState();
_controller = VideoPlayerController.asset('assets.mp4')
..initialize().then((_) {
_controller.setVolume(1.0); //video sound (volume)
_controller.setLooping(false); //do not repeat the video when finish
_controller.play(); //play the video
//navigate to the question page when the video is finished
Timer(
Duration(seconds: 38), //the wanted duration for the timer
() => Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const HomeScreen(),
)));
setState(() {});
});
}
@override
Widget build(BuildContext context) {
//fit to the screen
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return MaterialApp(
home: Stack(
children: <Widget>[
SizedBox.expand(
child: FittedBox(
fit: BoxFit.cover,
child: SizedBox(
width: width,
height: height,
child: VideoPlayer(_controller),
),
),
),
Container(
alignment: Alignment.topRight,
padding: EdgeInsets.all(30.0),
child: NiceButtons(
//A skip button to go to the questions page
stretch: false,
startColor: Colors.lightBlueAccent,
endColor: Colors.lightBlueAccent,
borderColor: Color(0xFF3489e9),
width: 100.0,
height: 60,
borderRadius: 60,
gradientOrientation: GradientOrientation.Horizontal,
onTap: (finish) {
//Navigate to the questions page
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const HomeScreen()),
);
_controller
.pause(); //stop the video when naviagte to the questions page
},
child: Text('skip',
textAlign: TextAlign.center,
style: TextStyle(
decoration: TextDecoration.none,
fontSize: 20.0,
color: Colors.white,
fontFamily: 'ReadexPro-Regular',
fontWeight: FontWeight.bold))),
),
],
),
debugShowCheckedModeBanner: false,
);
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
}
CodePudding user response:
declare timer
late Timer timer;
initialize timer
@override
void initState() {
super.initState();
timer = Timer(
Duration(seconds: 38),
() => Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const HomeScreen(),
)));
setState(() {});
}
@override
void dispose() {
super.dispose();
timer.cancel();
}
cancel timer
on onTap
or onPressed
function or dispose
the timer
timer.cancel();
CodePudding user response:
The solution is to define a reference to the timer and cancel it on dispose.
enstade of this:
Timer(
Duration(seconds: 38), //the wanted duration for the timer
() => Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const HomeScreen(),
)));
write this:
var timer = Timer(
Duration(seconds: 38), //the wanted duration for the timer
() => Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const HomeScreen(),
)));
and onDispose will be like this:
@override
void dispose() {
super.dispose();
_controller.dispose();
timer.cancel();
}
CodePudding user response:
to achive this you need to cancel timer when you click on skip button. so here i initialize timer in initstate method and when user click on skip button timer is cancelled and navigate to other page.
class _VideoAppState extends State<additionVideo> {
late VideoPlayerController _controller; //the controller of the video player
late Timer timer;
@override
void initState() {
super.initState();
_controller = VideoPlayerController.asset('assets.mp4')
..initialize().then((_) {
_controller.setVolume(1.0); //video sound (volume)
_controller.setLooping(false); //do not repeat the video when finish
_controller.play(); //play the video
//navigate to the question page when the video is finished
timer = Timer(
Duration(seconds: 38), //the wanted duration for the timer
() => Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const HomeScreen(),
)));
setState(() {});
});
}
@override
Widget build(BuildContext context) {
//fit to the screen
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return MaterialApp(
home: Stack(
children: <Widget>[
SizedBox.expand(
child: FittedBox(
fit: BoxFit.cover,
child: SizedBox(
width: width,
height: height,
child: VideoPlayer(_controller),
),
),
),
Container(
alignment: Alignment.topRight,
padding: EdgeInsets.all(30.0),
child: NiceButtons(
//A skip button to go to the questions page
stretch: false,
startColor: Colors.lightBlueAccent,
endColor: Colors.lightBlueAccent,
borderColor: Color(0xFF3489e9),
width: 100.0,
height: 60,
borderRadius: 60,
gradientOrientation: GradientOrientation.Horizontal,
onTap: (finish) {
timer.cancel();
//Navigate to the questions page
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const HomeScreen()),
);
_controller.pause(); //stop the video when naviagte to the questions page
},
child: Text('skip',
textAlign: TextAlign.center,
style: TextStyle(
decoration: TextDecoration.none,
fontSize: 20.0,
color: Colors.white,
fontFamily: 'ReadexPro-Regular',
fontWeight: FontWeight.bold))),
),
],
),
debugShowCheckedModeBanner: false,
);
}
@override
void dispose() {
super.dispose();
_controller.dispose();
timer.cancel();
}
}
CodePudding user response:
Try it out:
onTap: (finish) {
//Navigate to the questions page
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const HomeScreen()),
);
setState(() {
_controller
.pause();
});
//stop the video when naviagte to the questions page
},