當你第一眼看到這個標題的時候,肯定很驚訝。沒錯,我也覺得標題可能不規范,不過真的解決我在使用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()
方法的正確使用,網上還有更多介紹,我這里簡單做一個我遇到的問題以及解決方案的總結,分享給大家。
下面貼出完整的生命周期: