1. 程式人生 > >fragment的setUserVisibleHint方法詳解之不懂使用容易出大問題

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 {
               //載入資料
            }
        }
    }