Flutter: Call a function on a child widget's state

后端 未结 4 1727
小蘑菇
小蘑菇 2021-02-04 06:40

I\'ve created a stateful widget and its parent widget needs to call a function that lives in the child\'s state.

Specifically, I have a class PlayerContainer that create

4条回答
  •  无人共我
    2021-02-04 07:09

    State management is the one thing they dropped the ball on with respect to this framework. I've used static variables (if I need to share data between states) and GlobalKeys (for just one quick, dirty solution) to get this done. We're supposed to use InheritedWidgets, it's just extremely out-of-the-way for something that should be simple. I usually just do this:

    // top of code here - this is global
    final videoPlayerKey = GlobalKey();
    
    class VideoPlayerContainer extends StatelessWidget {
        static VideoPlayerController videoPlayerController;
        ...
        @override
        Widget build(BuildContext context) {
            videoPlayerController = VideoPlayerController(...);
            // the static variable is empty until the container is built
    
            return Container(
                child: VideoPlayer(
                    child: PlayButton(onTap: () => 
                        videoPlayerKey.currentState.setState(
                        () => VideoPlayerContainer.videoPlayerController.play();
                    ))
                ),
            ); 
        }
    }
    
    class VideoPlayer extends StatefulWidget {
    final Key key = videoPlayerKey;
        ...
    }
    
    class VideoPlayerState extends State {
        ...
    }
    

    We need to get videoPlayerKey's currentState to use setState() and re-run the build method so it knows to update, and then we can grab the controller for the player wherever it is stored using the static variable. It could be in VideoPlayer or anywhere else that's not here in VideoPlayerContainer, because it's static - it's just important that you assign the GlobalKey to whatever Widget will need to be rebuilt. It will work because whenever a user could tap the button, the static variable will have been set for any void to read by VideoPlayerContainer's build() method. For this method, it's important to note that it's more important that you attach the GlobalKey to the element that needs to be updated - you can put the static pageController literally wherever and set it from wherever within a build() or initState().

    Notes: This will not work if you try to use multiple VideoPlayers in one layout, because GlobalKeys must be unique, and all VideoPlayers will be initialized with the same key. This is more of a dirty hack than anything. I am working on a more robust state management solution at the moment to solve stuff like this.

提交回复
热议问题