您好,登錄后才能下訂單哦!
一個Activity以ViewPager(或其他容器)與多個Fragment來結合使用,如果每個Fragment都要去加載數據(本地或網絡),那么這個activity剛創建的時候就要初始化大量的資源。那能不能做到當切換到這個fragment的時候才去初始化呢?
答案就在setUserVisibleHint里。該方法告訴系統這個Fragment的UI是否可見。所以我們通過該方法,在Fragment可見時再去初始化就行了。
public abstract class LazyFragment extends Fragment {
protected boolean isVisible;
/**
*在這里實現Fragment數據的緩加載。
*/
@override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (getUserVisibleHint()) {
isVisible = true;
onVisible();
} else {
isVisible = false;
onInvisible();
}
}
protected void onVisible() {
lazyLoad();
}
protected abstract void lazyLoad();
protected void onInvisible(){}
}
問題:為什么不在getUserVisibleHint里面直接處理事情,而是寫一個抽象函數呢?
這樣做是為了重用。因為fragment中,我們還需要創建視圖,可能還需要在該Fragment不可見時進行其他小量的初始化操作(如初始化需要通過AIDL調用的遠程服務)。而setUserVisibleHint()是在onCreateView之前調用的,在視圖未初始化時,在lazyload當中使用就會報空指針。而把lazyLoad抽離成一個方法,那么它的子類就可以這樣做:
public class OpenResultFragment extends LazyFragment {
//標志位,標志已經初始化完成(防止onCreateView未調用之前就調用該方法導致空指針)
private Boolean isPrepared;
@override
public View onCreateView() {
View view = inflater.inflate(R.layout.fragment, container, false);
//初始化控件
isPrepared = true;
lazyLoad();
return view;
}
@override
protected void lazyLoad() {
//在調用了onCreateView后并且fragment的UI是可見的就填充數據
//如果是要下載網絡數據,不是給view填充數據之類的,就不需要isPrepared參數了
if (!isPrepared || !isVisible) return;
//填充各控件的數據
}
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。