首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >颤振:对子部件的状态调用函数

颤振:对子部件的状态调用函数
EN

Stack Overflow用户
提问于 2018-05-28 00:51:22
回答 4查看 29.1K关注 0票数 18

我已经创建了一个有状态的小部件,它的父小部件需要调用一个处于子状态的函数。

具体来说,我有一个类PlayerContainer,它为VideoPlayerController创建一个VideoPlayer并有一个成员变量。当我按play按钮时,我的主类需要调用State的VideoPlayerController上的play(),所以我在State类中创建了一个函数,但是我不知道如何从父小部件访问该函数。

这可能吗?还是我搞错了?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-05-28 01:15:43

使用一个简单的应用程序,您可以在与VideoPlayer相同的Widget中创建play按钮。通过将PlayerContainer与其父控件结合起来,您将增加Widget范围的大小,以便所有需要访问它的内容都是单个更大Widget的一部分。

子Widget受祖先影响的主要方式是:使用不同的参数进行重建,或者监听祖先更改的内容。对于后者,您可以在某个地方使用InheritedWidget。如果子引用的是InheritedWidget,则当IW发生变化时,它将被重新构建。另一种方法是侦听祖先生成的事件流。

您可能会发现,只在单个构建中构建整个页面是最简单的,直到这变得难以处理为止。

票数 0
EN

Stack Overflow用户

发布于 2018-11-09 22:58:49

我知道我去派对已经很晚了,但我有件事我觉得可能会有帮助。因此,您需要在VideoPlayerController类中做四件事:

  1. 创建状态类的实例。
  2. 创建一个可在PlayerContainer类中访问的方法(play)
  3. 在您的方法中,使用VideoPlayerControllerState实例在状态类中调用该方法。
  4. 最后,当您使用createState时,使用您已经创建的实例这样做。
代码语言:javascript
复制
class VideoPlayerController extends StatefulWidget {
  final VideoPlayerControllerState vpcs = VideoPlayerControllerState();

  void play() {
    vpcs.play();
  }

  @override
  State<StatefulWidget> createState() => vpcs;
}

正如您所看到的,play方法使用vpcs ( VideoPlayerControllerState实例)调用已经在状态类中的play方法。

在PlayerContainer类中,使用成员变量调用play方法。

代码语言:javascript
复制
class PlayerContainerState extends State<PlayerContainer> {
  VideoPlayerController _vpc;

  @override
  void initState() {
    super.initState();
    _vpc = VideoPlayerController();
  }
  ...

  void _handlePressPlay(){
    _vpc.play();
  } 
  ...

  @override
  Widget build(BuildContext context) {
    return ... //your video player widget using _vpc as your VideoPlayerController
      _vpc,
    );
  }
}

您可以从播放按钮的_handlePressPlay()方法调用onPressed。或者,只需将_vpc.play()放入onPressed方法。你的选择:-)。

票数 33
EN

Stack Overflow用户

发布于 2018-05-28 03:09:59

关于这个框架,国家管理是他们放弃的一件事。我使用了静态变量(如果需要在状态之间共享数据)和GlobalKeys (仅用于一种快速、肮脏的解决方案)来完成这一任务。我们应该使用InheritedWidgets,这对于一些应该很简单的事情来说是非常离谱的。我通常就是这么做的:

代码语言:javascript
复制
// 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<VideoPlayer> {
    ...
}

我们需要让视频player的currentState使用setState()并重新运行构建方法,以便它知道如何更新,然后我们可以使用静态变量获取播放器的控制器。它可能在VideoPlayer中,也可能在其他不在VideoPlayerContainer中的地方,因为它是静态的--重要的是将GlobalKey分配给任何需要重建的GlobalKey。它将工作,因为每当用户可以点击按钮时,静态变量就会被设置为由VideoPlayerContainer的build()方法读取的任何空白。对于这种方法,需要注意的是,更重要的是将GlobalKey附加到需要更新的元素上--您可以将静态pageController放在任意位置,并在构建()或initState()中的任何地方设置它。

注意:如果您尝试在一个布局中使用多个VideoPlayers,这将无法工作,因为GlobalKeys必须是唯一的,并且所有VideoPlayers都将使用相同的键初始化。这更像是一次肮脏的黑客攻击。目前,我正在研究一种更健壮的状态管理解决方案,以解决类似的问题。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50557842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档