I have set my app screen orientation to portrait by adding
android:screenOrientation="portrait"
to my android/app/src/main/AndroidManifest.xml and so when I start my app it's locked to portrait mode. And I am happy about it.
I have a page that shows videos and I am using the Chewie plugin which plays the video in landscape mode all good.
Here is my code:
class _VideoState extends State<Video> {
ChewieController _chewieController;
@override
void initState() {
super.initState();
_chewieController = ChewieController(
fullScreenByDefault: true,
videoPlayerController: widget.videoPlayerController,
aspectRatio: 16 / 9,
autoInitialize: true,
autoPlay: true,
allowedScreenSleep: false,
allowFullScreen: true,
deviceOrientationsAfterFullScreen: [
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
],
errorBuilder: (context, e) {
return Center(
child: Text('Some error occurred'),
);
},
);
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Chewie(
controller: _chewieController,
),
);
}
@override
void dispose() {
widget.videoPlayerController.dispose();
widget.videoPlayerController.pause();
_chewieController.dispose();
super.dispose();
}
}
This works fine till I run the video completely in landscape more with no issues, but when I pop back to my previous page my app, which should be in portrait mode, is now in landscape mode which I don't want to happen. I want my app to be still locked to portrait mode.
I tried adding SystemChrome.setPreferredOrientations to my video page and dispose off, but this did not work either.
Here is the error I get:
══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
The following assertion was thrown while dispatching notifications for VideoPlayerController:
'package:flutter/src/widgets/framework.dart': Failed assertion: line 4182 pos 12:
'_debugLifecycleState != _ElementLifecycle.defunct': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially
more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=BUG.md
When the exception was thrown, this was the stack:
#2 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4182:12)
#3 State.setState (package:flutter/src/widgets/framework.dart:1260:14)
#4 _VideoState.initState.<anonymous closure> (package:/widget/page/video.dart:65:9)
#5 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:209:21)
#6 ValueNotifier.value= (package:flutter/src/foundation/change_notifier.dart:276:5)
#7 VideoPlayerController.pause (package:video_player/video_player.dart:360:5)
#8 _VideoState.dispose (package:/widget/page/video.dart:107:34)
#9 StatefulElement.unmount (package:flutter/src/widgets/framework.dart:4773:12)
(elided 5 frames from class _AssertionError and dart:async)
The VideoPlayerController sending notification was:
VideoPlayerController#2afe2(VideoPlayerValue(duration: 0:10:55.430000, size: Size(1920.0, 1080.0),
position: 0:10:55.430000, caption: Instance of 'Caption', buffered: [DurationRange(start:
0:00:00.000000, end: 0:10:55.430000)], isPlaying: false, isLooping: false, isBuffering:
falsevolume: 1.0, errorDescription: null))
════════════════════════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by foundation library ════════════════════════════════════════════════════
The following assertion was thrown while dispatching notifications for VideoPlayerController:
'package:flutter/src/widgets/framework.dart': Failed assertion: line 4182 pos 12: '_debugLifecycleState != _ElementLifecycle.defunct': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=BUG.md
When the exception was thrown, this was the stack:
#2 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4182:12)
#3 State.setState (package:flutter/src/widgets/framework.dart:1260:14)
#4 _VideoState.initState.<anonymous closure> (package:/widget/page/video.dart:65:9)
#5 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:209:21)
#6 ValueNotifier.value= (package:flutter/src/foundation/change_notifier.dart:276:5)
...
The VideoPlayerController sending notification was: VideoPlayerController#2afe2(VideoPlayerValue(duration: 0:10:55.430000, size: Size(1920.0, 1080.0), position: 0:10:55.430000, caption: Instance of 'Caption', buffered: [DurationRange(start: 0:00:00.000000, end: 0:10:55.430000)], isPlaying: false, isLooping: false, isBuffering: falsevolume: 1.0, errorDescription: null))
Here is my updated code:
class Video extends StatefulWidget {
final VideoPlayerController videoPlayerController;
const Video({
Key key,
@required this.videoPlayerController,
}) : super(key: key);
@override
_VideoState createState() => _VideoState();
}
class _VideoState extends State<Video> {
ChewieController _chewieController;
@override
void initState() {
super.initState();
_chewieController = ChewieController(
fullScreenByDefault: true,
videoPlayerController: widget.videoPlayerController,
aspectRatio: 16 / 9,
autoInitialize: true,
autoPlay: true,
allowedScreenSleep: false,
allowFullScreen: true,
deviceOrientationsAfterFullScreen: [
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
],
errorBuilder: (context, e) {
return Center(
child: Text('Some error occurred'),
);
},
);
}
@override
Widget build(BuildContext context) {
//final length = MediaQuery.of(context).size;
return SingleChildScrollView(
child: VideoScaffold(
Chewie(
controller: _chewieController,
),
),
);
}
@override
void dispose() {
widget.videoPlayerController.dispose();
widget.videoPlayerController.pause();
_chewieController.dispose();
super.dispose();
}
}
class VideoScaffold extends StatefulWidget {
const VideoScaffold({Key key, this.child}) : super(key: key);
final Widget child;
@override
State<StatefulWidget> createState() => _VideoScaffoldState();
}
class _VideoScaffoldState extends State<VideoScaffold> {
@override
void initState() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);
AutoOrientation.landscapeAutoMode();
super.initState();
}
@override
Widget build(BuildContext context) {
return widget.child;
}
@override
dispose() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
AutoOrientation.landscapeAutoMode();
AutoOrientation.portraitUpMode();
super.dispose();
}
}
Now after doing Navigator.of(context).pop
from the video page, my app stays in portrait mode, but now the issue is I get the above error. How do I get rid of the error?
you need to add the following to you main.dart
DeviceOrientation.portraitUp,
example
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
//ensures portrait at all times. you can override this if necessary
]);
return MaterialApp(
home: Scaffold(
body: Center(child: Text("A Flutter Example!")),
),
);
}
}
you need to dipose the widgets when done and revert to potrait
@override
dispose() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
super.dispose();
}