我已经创建了一个有状态的小部件,它的父小部件需要调用一个处于子状态的函数。
具体来说,我有一个类PlayerContainer,它为VideoPlayerController创建一个VideoPlayer并有一个成员变量。当我按play按钮时,我的主类需要调用State的VideoPlayerController上的play(),所以我在State类中创建了一个函数,但是我不知道如何从父小部件访问该函数。
这可能吗?还是我搞错了?
发布于 2018-05-28 01:15:43
使用一个简单的应用程序,您可以在与VideoPlayer相同的Widget中创建play按钮。通过将PlayerContainer与其父控件结合起来,您将增加Widget范围的大小,以便所有需要访问它的内容都是单个更大Widget的一部分。
子Widget受祖先影响的主要方式是:使用不同的参数进行重建,或者监听祖先更改的内容。对于后者,您可以在某个地方使用InheritedWidget。如果子引用的是InheritedWidget,则当IW发生变化时,它将被重新构建。另一种方法是侦听祖先生成的事件流。
您可能会发现,只在单个构建中构建整个页面是最简单的,直到这变得难以处理为止。
发布于 2018-11-09 22:58:49
我知道我去派对已经很晚了,但我有件事我觉得可能会有帮助。因此,您需要在VideoPlayerController类中做四件事:
PlayerContainer类中访问的方法(play)VideoPlayerControllerState实例在状态类中调用该方法。createState时,使用您已经创建的实例这样做。class VideoPlayerController extends StatefulWidget {
final VideoPlayerControllerState vpcs = VideoPlayerControllerState();
void play() {
vpcs.play();
}
@override
State<StatefulWidget> createState() => vpcs;
}正如您所看到的,play方法使用vpcs ( VideoPlayerControllerState实例)调用已经在状态类中的play方法。
在PlayerContainer类中,使用成员变量调用play方法。
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方法。你的选择:-)。
发布于 2018-05-28 03:09:59
关于这个框架,国家管理是他们放弃的一件事。我使用了静态变量(如果需要在状态之间共享数据)和GlobalKeys (仅用于一种快速、肮脏的解决方案)来完成这一任务。我们应该使用InheritedWidgets,这对于一些应该很简单的事情来说是非常离谱的。我通常就是这么做的:
// 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都将使用相同的键初始化。这更像是一次肮脏的黑客攻击。目前,我正在研究一种更健壮的状态管理解决方案,以解决类似的问题。
https://stackoverflow.com/questions/50557842
复制相似问题