Flutter VideoPlayerController “在构建期间调用了 setState() 或 markNeedsBuild()。”
Posted
技术标签:
【中文标题】Flutter VideoPlayerController “在构建期间调用了 setState() 或 markNeedsBuild()。”【英文标题】:Flutter VideoPlayerController "setState() or markNeedsBuild() called during build." 【发布时间】:2019-02-19 23:53:04 【问题描述】:我正在播放视频,没有问题,但是当导航到另一个页面时,控制台会这样说。
我尝试了我想出的所有方法,例如检查 mounted
是否有效。
我错过了什么?有人知道怎么解决吗?
flutter:在为 VideoPlayerController 调度通知时抛出以下断言: 颤振:在构建期间调用 setState() 或 markNeedsBuild()。 颤振:这个 VideoProgressIndicator 小部件无法标记为需要构建,因为框架是 颤振:已经在构建小部件的过程中。小部件可以在期间标记为需要构建 颤振:仅当其祖先之一当前正在构建时才构建阶段。这个例外是允许的,因为 Flutter:框架在子组件之前构建父组件,这意味着脏的后代将永远是 扑:建成。否则,框架可能不会在此构建阶段访问此小部件。 颤振:调用 setState() 或 markNeedsBuild() 的小部件是: 颤振:VideoProgressIndicator(状态:_VideoProgressIndicatorState#09ac7)
代码:
class _VideoScreenState extends State<VideoScreen>
VideoPlayerController _controller;
FadeAnimation imageFadeAnim =
new FadeAnimation(child: const Icon(Icons.play_arrow, size: 100.0));
VoidCallback listener;
bool _isPlaying = false;
List<String> videos = [
'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_20mb.mp4',
];
_VideoScreenState()
listener = ()
if (mounted) setState(() );
;
Future _videoOnTap() async
if (!_controller.value.initialized)
return;
if (_controller.value.isPlaying)
imageFadeAnim = new FadeAnimation(
child: Icon(Icons.pause,
color: Colors.white.withOpacity(0.3), size: 75.0));
await _controller.pause();
else
imageFadeAnim = new FadeAnimation(
child: Icon(Icons.play_arrow,
color: Colors.white.withOpacity(0.3), size: 75.0));
await _controller.play();
Future _startVideoPlayer(int index) async
if (_controller != null)
await _controller.dispose();
_controller = VideoPlayerController.network(videos[index])
..addListener(()
final bool isPlaying = _controller.value.isPlaying;
if (isPlaying != _isPlaying)
if (mounted)
setState(()
_isPlaying = isPlaying;
);
)
..initialize().then((_) async
await _controller.play();
if (mounted) setState(() );
);
@override
void initState()
SystemChrome.setEnabledSystemUIOverlays([]);
_startVideoPlayer(0);
super.initState();
@override
void deactivate()
_controller?.setVolume(0.0);
_controller?.removeListener(listener);
super.deactivate();
@override
void dispose()
_controller?.dispose();
super.dispose();
@override
Widget build(BuildContext context)
final List<Widget> children = <Widget>[
new GestureDetector(
child: new Center(
child: _controller.value.initialized
? new AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: new VideoPlayer(_controller))
: new Container(),
),
onTap: _videoOnTap,
),
new Align(
alignment: Alignment.topCenter,
child: new VideoProgressIndicator(
_controller,
allowScrubbing: false,
colors: VideoProgressColors(
backgroundColor: Colors.black.withOpacity(0.5),
playedColor: Colors.white),
),
),
new Center(child: imageFadeAnim),
];
return new Scaffold(
backgroundColor: Colors.black,
body: new SafeArea(
top: true,
left: false,
right: false,
bottom: false,
child: new Stack(
fit: StackFit.passthrough,
children: children,
),
),
);
class FadeAnimation extends StatefulWidget
final Widget child;
final Duration duration;
FadeAnimation(this.child, this.duration: const Duration(milliseconds: 300));
@override
_FadeAnimationState createState() => new _FadeAnimationState();
class _FadeAnimationState extends State<FadeAnimation>
with SingleTickerProviderStateMixin
AnimationController animationController;
@override
void initState()
super.initState();
animationController =
new AnimationController(duration: widget.duration, vsync: this);
animationController.addListener(()
if (mounted)
setState(() );
);
animationController.forward(from: 0.0);
@override
void deactivate()
animationController.stop();
super.deactivate();
@override
void didUpdateWidget(FadeAnimation oldWidget)
super.didUpdateWidget(oldWidget);
if (oldWidget.child != widget.child)
animationController.forward(from: 0.0);
@override
void dispose()
animationController.dispose();
super.dispose();
@override
Widget build(BuildContext context)
return animationController.isAnimating
? new Container(
width: 75.0,
height: 75.0,
decoration: new BoxDecoration(
color: Colors.black.withOpacity(0.01),
shape: BoxShape.circle,
),
child: widget.child,
)
: new Container();
【问题讨论】:
我也有同样的问题。有什么解决办法吗? 解决了什么问题? 这里也一样,有人提出过解决办法吗? 它肯定与 deactivate() 中的 _controller?.setVolume(0.0) 有关。没有机会更详细地研究它。但我猜该代码中的某个地方可能会调用 setState 本身。 【参考方案1】:在 initState 中初始化你的 animationController 并将监听器添加到 didchangeDependencies
@override
void initState()
super.initState();
animationController =
new AnimationController(duration: widget.duration, vsync: this);
@override
void didChangeDependencies(
super.didChangeDependencies();
animationController.addListener(()
if (mounted)
setState(() );
);
animationController.forward(from: 0.0);
)
【讨论】:
以上是关于Flutter VideoPlayerController “在构建期间调用了 setState() 或 markNeedsBuild()。”的主要内容,如果未能解决你的问题,请参考以下文章
[Flutter] flutter项目一直卡在 Running Gradle task 'assembleDebug'...
flutter 日志输出,Flutter打印日志,flutter log,flutter 真机日志
Flutter开发 Flutter 包和插件 ( Flutter 包和插件简介 | 创建 Flutter 插件 | 创建 Dart 包 )
如何解决flutter gradle build error?C:\flutter\packages\flutter_tools\gradle\flutter.gradle' line: 991