fragment的setUserVisibleHint方法詳解之不懂使用容易出大問題
一開始不知道這個方法,用到tablayout+ viewpager,viewpager裡面包含的是fragment,有這樣的需求就是,每次滑動需要重新整理當前頁面,百度一看,有兩個方法可以實現,1.setUserVisibleHint 2.onHiddenChanged
如果使用的是上面這張viewpager+tablayout 這種方法,用setUserVisibleHint可以有效的實現重新整理資料,而onHiddenChanged這個是需要add、show 、hide隱藏這種方法,切不會走生命週期,如果不對請指正,這裡講解的是setUserVisibleHint方法。
來看張fragment生命週期圖;
可以先記下!!!
這裡用上setUserVisibleHint這個方法,本以為只是一個簡單方法,沒想到用了之後出現了大問題,
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if(isVisibleToUser){
}
}
如果是true就直接載入資料,按理說是對的啊,自己可以親自試驗一下發現載入了很多資料,還有用可能是沒有資料,這是為什麼呢,因為setUserVisibleHint方法的生命週期先與oncreate,當setUserVisbleHint把資料載入完了之後,onCreate還沒有載入完成,造成問題所在。繼續往下走。
當fragment有3的時候,setUserVisibleHint裡面的方法執行了什麼。
log
執行了3個false1個true,當顯示出第一個介面的時候,isVisibleToUser是true。
把onResume一起列印一下。
看下執行過程
先執行setUserVisibleHint --- oncreate1 --onresume1 - oncreate2 - onResume2- oncreate3 -onResume3應該是這樣的,剛剛debug就忘了,,自己可以列印一下,
這裡的fragment是一個,而不是三個分開的。
其實知道了這些執行的生命週期過程,自認而然就ok了,不管是懶載入還是....都是一個道理。
順便附上程式碼
private var isFristResume = true
private var isFristVisble = true
override fun onResume() {
super.onResume()
if (isFristResume){
isFristResume = false
return
}
if (userVisibleHint){
//載入資料
}
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if(isVisibleToUser){
if (isFristVisble){
isFristVisble = false
//載入資料這裡為什麼要載入呢,是因為前面的log,三個false和一個true
//第一次初始化的時候會執行一個true,也就是第一個可見的介面,當滑動到第二的介面時候,isFristvisble並不是false還是true,不會執行else,不會載入資料,只有當第二次的時候才會載入。這裡只會執行三次,,而是一直會執行else的資料
}else {
//載入資料
}
}
}