当你第一眼看到这个标题的时候,肯定很惊讶。没错,我也觉得标题可能不规范,不过真的解决我在使用Fragment时遇到的坑,这里分享出来,供大家参考,一起交流。
先来描述一下我的APP中使用到Fragment的功能和遇到的问题,第一个Fragment里是一个视频播放控件,希望在切换到其他Fragment的时候,暂停视频;再次回到这个Fragment时恢复播放。由于我使用的是hide和show的方式进行的Fragment之间的切换,每个Fragment只被初始化一次。那么问题来了,我尝试按照网上说的Fragment的生命周期,在onPause或onStop方法中暂停,在onResume中恢复播放,可是发现压根没走这些方法,onPause等方法不会调用,onResume只在刚进入是调用了一次,也没法做到让视频暂停。
话说回来,Fragment的使用越来越普遍了,掌握它的生命周期以及注意事项是非常有必要的,首先
All subclasses of Fragment must include a public empty constructor. The framework will often re-instantiate a fragment class when needed, in particular during state restore, and needs to be able to find this constructor to instantiate it.
也就是说每个继承Fragment的类都必须要有公开的构造方法,以便fragment能在需要的时候还原原来的状态。感觉很难理解?通俗的说就是:SDK还原fragment数据的时候,肯定先通过调用XXX.newInstance()方法,获取到fragment的实例对象。这就是为什么要提供一个公开的构造方法的原因了!
其次,生命周期是必须了解的,这个就没必要废话了,网上搜下到处都是。
重点来了,跟我使用Fragment遇到的问题一样,这里再举一个Fragment使用时常遇到的情况,在一个Activity中通过菜单选项的点击来切换不同的Fragment,通常是需要保存Fragment的状态的,比如编辑个人信息模块时点击其他菜单,返回时你编辑的信息应该要保存的,而不是再次初始化。这时就该使用Fragment的hide/show方法了。
很快你就会发现Fragment的生命周期怎么不走了?
这时此方法 onHiddenChanged派上用场了,当Fragment隐藏时,该方法会调用传入参数为true表示该Fragment被隐藏了,当Fragment调用了show方法后,该方法传入的参数为false,表示该Fragment正在显示!
所以总结起来,如果使用hide/show方法来控制Fragment的使用时,原本需要在onResume以及onPause方法做的事情就可以迁移到 onHiddenChanged时进行管理,如:
if (hidden) {// 不在最前端界面显示
} else {// 重新显示到最前端
}
这样就能完美实现当前Fragment在隐藏和显示时分别需要做的事了,我的APP视频暂停与播放的问题就解决了。
附上我的APP中使用的代码,这样就能理解了:
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden) { //不在最前端界面显示
mVideoView.pause();
} else { //重新显示到最前端
mVideoView.start();
}
}
关于add()
, show()
, hide()
, replace()
方法的正确使用,网上还有更多介绍,我这里简单做一个我遇到的问题以及解决方案的总结,分享给大家。
下面贴出完整的生命周期: