代码之家  ›  专栏  ›  技术社区  ›  Daibaku

颤振VideoPlayerController“在生成过程中调用了setState()或markNeedsBuild()。”

  •  1
  • Daibaku  · 技术社区  · 8 年前

    我正在播放视频,没有问题,但当导航到另一个页面时,控制台会这样说。
    mounted
    我错过了什么?有人知道怎么修理吗?

    颤振:为VideoPlayerController发送通知时引发以下断言:
    颤振:在生成期间调用setState()或markNeedsBuild()。

    颤振:已经在构建小部件的过程中。可以将小部件标记为需要在
    颤振:仅当其祖先之一当前正在构建时才处于构建阶段。允许此异常是因为

    颤振:建造。否则,框架可能不会在此构建阶段访问此小部件。
    颤振:调用setState()或markNeedsBuild()的小部件是:

    代码:

    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();
          }
        }
    
    0 回复  |  直到 8 年前
        1
  •  0
  •   Nabin Dhakal    5 年前

    在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);
    })