fragment 的懶加載
- 懶加載
什么是懶加載:
只有在 fragment 顯示在界面的時(shí)候,才進(jìn)行數(shù)據(jù)的加載
懶加載類別:
不同 fragment 的添加方式,需要采用不同的懶加載處理方法
fragment 添加方式:
- replace()
- add()/hide()/show()
- viewpager + fragment
replace()
/**
* 以replace()的方式添加fragment到指定布局R.id.layout_fragment
*/
private void showFragment(Fragment fragment) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.layout_fragment, fragment);
transaction.commit();
}
每次均是添加新的 fragment 實(shí)例,數(shù)據(jù)需要重新加載
選擇合適的生命周期即可
add()/hide()/show()
/**
* 以add()/hide()/show()的方式添加
* 判斷fragment是否已被添加進(jìn)入fragmentManager
* 已添加:直接顯示
* 未添加:指定布局R.id.layout_content,add
*/
private void showFragment(Fragment newFragmeent) {
if (newFragmeent != currentFrament ) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
if (!newFragmeent.isAdded()) {
transaction
.hide(currentFrament)
.add(R.id.layout_content, newFragmeent)
.commit();
} else {
transaction
.hide(currentFrament)
.show(newFragmeent)
.commit();
}
currentFrament = newFragmeent
}
}
- fragment 未被添加進(jìn)入 fragmentManager,采用 add 的方式添加 :
觸發(fā)生命周期 與 replace()的處理方式相同,選擇合適生命周期即可
- fragment 已被添加進(jìn)入 fragmentManager,采用 show 的方式:
觸發(fā) onHiddenChanged(boolean hidden) 一般無(wú)需處理加載,數(shù)據(jù)已經(jīng)在 add()時(shí)通過(guò)生命周期加載過(guò)了
/**
* show()/hide()會(huì)觸發(fā) add()不會(huì)觸發(fā)
* 此方法只是用于感知show()和hide()
*/
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if(hidden){
//TODO now invisible to user
} else {
//TODO now visible to user
}
}
viewpager + fragment
- 只有在 adapter 是 FragmentPagerAdapter 或 FragmentStatePagerAdapter 才有效果
需要注意的是:
位于 FragmentPagerAdapter 或 FragmentStatePagerAdapter 當(dāng)中的fragment,setUserVisibleHint(boolean isVisibleToUser)的調(diào)用時(shí)機(jī)分為兩種
- fragment 實(shí)例化 : 所有生命周期之前
- fragment 只是切換顯隱,但并未實(shí)例化 : 顯示或隱藏的時(shí)候
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHasCreatedView = false;
mHasLoadedOnce = false;
isFragmentVisible = false;
}
/**
* 兩步分別處理兩個(gè)fragment
* 1. 由不可見切換為可見的fragment
* 2. 由可見切換為不可見的fragment
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
//通過(guò)mRootView是否為null來(lái)判斷是否已經(jīng)初始化完成(也就是判斷具體是通過(guò)哪一次觸發(fā))
if (mRootView == null) {
return;
}
//初始化完成,標(biāo)記,代表是由第二種方式觸發(fā)
mHasCreatedView = true;
//isVisibleToUser == true,表示fragment由不可見切換為可見
if (isVisibleToUser) {
onFragmentVisibleChange(true);
isFragmentVisible = true;
changeToVisiable();
return;
}
//可見的fragment由可見切換為不可見
if (isFragmentVisible) {
onFragmentVisibleChange(false);
isFragmentVisible = false;
}
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
...
//通過(guò)第一種方式觸發(fā)時(shí),并沒(méi)有進(jìn)行加載數(shù)據(jù)
if (mHasCreatedView){
return;
}
//進(jìn)行第一種方式觸發(fā)時(shí)的數(shù)據(jù)加載
if (getUserVisibleHint()) {
onFragmentVisibleChange(true);
isFragmentVisible = true;
changeToVisiable();
}
}
private void changeToVisiable(){
//從未加載過(guò),則加載
if (!mHasLoadedOnce) {
onLazyLoad();
}
}
/**
* 可見性的切換觸發(fā)
*
*/
protected void onFragmentVisibleChange(boolean isvisible) {
}
/**
* 懶加載
*/
protected void onLazyLoad() {
//已經(jīng)加載過(guò),標(biāo)記
mHasLoadedOnce = true;
}