前言
大家應(yīng)該都知道毯侦,F(xiàn)ragment的加載方式有倆種:靜態(tài)加載和動(dòng)態(tài)加載;
對(duì)于這倆種具垫,不用縮侈离!我猜大家肯定更喜歡用后者吧,畢竟咱都是愛用動(dòng)的boy嘛 嘖嘖嘖~好像跑偏了
哈哈筝蚕,顏歸正傳卦碾!上!代起宽!碼洲胖!
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rootview"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<!--其余代碼省略-->
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
眼熟不?然后配合下面這段代碼
getSupportFragmentManager().beginTransaction().replace(R.id.container,new ProcessDetailFragment()).commit();
就可以實(shí)現(xiàn)fragment的動(dòng)態(tài)加載了坯沪,是不是很開心绿映?
然鵝,當(dāng)我打開Android Studio 的Layout Inspector[1]的時(shí)候,我并不怎么開森
為毛fragment布局不是直接替換掉container布局而是在它里面2嫦摇Xひ弧!
其實(shí)一般情況也沒啥淹冰,只是如果是這里库车,那!就樱拴!堅(jiān)柠衍!決!不疹鳄!能拧略!忍芦岂!眼神好的童鞋可能發(fā)現(xiàn)了瘪弓,這個(gè)fragment里面是個(gè)典型的ViewPager+Tablayout
組合,而ViewPager里面又會(huì)有一堆fragment ,所以布局結(jié)構(gòu)那叫一個(gè)復(fù)雜禽最,這種布局哪怕多一層嵌套都是會(huì)相當(dāng)影響UI加載速度滴啊腺怯,所以,必須干掉它川无!
But How呛占?
聰明的你肯定想到了 哈哈 沒錯(cuò)!靜態(tài)加載fragment懦趋!于是晾虑,代碼我改改改
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rootview"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<!--其余代碼省略-->
<fragment
android:id="@+id/fragView"
android:name="com.xxx.ProcessDetailFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
運(yùn)行代碼,打開視圖檢查
怎么感覺好像故事快要講完了? 哈哈 仅叫,撇了一眼標(biāo)題帜篇,好像又跑題了 !
當(dāng)然木有跑題诫咱! 啰嗦了這么多笙隙,其實(shí)是在為后文作鋪墊哦
其實(shí)這是在復(fù)現(xiàn)當(dāng)時(shí)項(xiàng)目開發(fā)中一步步遇到問題解決問題的過程,沒有上述問題的粗現(xiàn)坎缭,接下來要講的東東也就不會(huì)發(fā)生了哦 所以算是個(gè)前情概要吧 就像看電影一樣 嘿嘿 大家多擔(dān)待
不呼不喚竟痰,我始出來!
現(xiàn)在視圖層級(jí)已經(jīng)達(dá)到我們的預(yù)期了掏呼,可是坏快!問題又粗線了,這個(gè)項(xiàng)目的viewPager里面是一個(gè)個(gè)fragment憎夷,其代表的是TabLayout中一個(gè)個(gè)菜單的詳情頁面假消,每個(gè)詳情頁面中數(shù)據(jù)會(huì)有操作,然后當(dāng)其中某個(gè)fragment中數(shù)據(jù)變化之后會(huì)影響其它fragment的數(shù)據(jù)和菜單的展示岭接,因此富拗,在每一次數(shù)據(jù)變化的時(shí)候臼予,我們需要刷新整個(gè)ProcessDetailFragment!
HOW 2 ?
最簡單的辦法啃沪,就是用新創(chuàng)建的ProcessDetailFragment替換掉目前的ProcessDetailFragment粘拾,然后新的ProcessDetailFragment會(huì)重新加載更新后的數(shù)據(jù)并展示,So Easy?
于是创千,按照這個(gè)想法缰雇,順便回想一下動(dòng)態(tài)加載fragment的代碼,fragment動(dòng)態(tài)加載的時(shí)候追驴,是需要指定容器布局id的械哟,代碼執(zhí)行后新fragment的布局會(huì)加入到這個(gè)容器布局中,所以如果我們要用新的ProcessDetailFragment替換掉原有的ProcessDetailFragment其實(shí)是不可行的殿雪!
什么暇咆,你不信,那我們用代碼來說話丙曙!
按照動(dòng)態(tài)加載fragment的方式爸业,用新的ProcessDetailFragment替換掉原來布局中的ProcessDetailFragment,注意下面代碼容器id為R.id.fragView亏镰,也就是fragment在xml中聲明的id
public void refresh() {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragView, new ProcessDetailFragment())
.commit();
}
然后看看新的視圖結(jié)果:
也許有些童鞋會(huì)說扯旷,先remove掉原來的ProcessDetailFragment在用新的fragment執(zhí)行replace就好啊,但其實(shí)如果用過靜態(tài)加載fragment的童鞋肯定知道索抓,F(xiàn)ragmentTransaction的remove針對(duì)靜態(tài)加載的fragment是無效的钧忽,而且本人也在此親測,在執(zhí)行remove后布局結(jié)構(gòu)依然和上圖一致
我有個(gè)大膽的想法
既然replace會(huì)將fragment加入到指定容器id布局之下逼肯,那么我們將這個(gè)容器id設(shè)置為原ProcessDetailFragment的父容器CoordinatorLayout的id,藍(lán)后在父容器中remove掉舊的ProcessDetailFragment布局視圖不就好了耸黑?
OL, 開干汉矿!
新的代碼:
//processDetailFragment 為目前布局中加載的fragment的引用
public void refresh() {
if (processDetailFragment != null) {
//新的ProcessDetailFragment
ProcessDetailFragment fragment = new ProcessDetailFragment();
//和老fragment中的布局參數(shù)保持一致 該方法需要自定義實(shí)現(xiàn)
//該方法可保證新的fragment布局和原fragment大小,行為一致
fragment.setLayoutParams((CoordinatorLayout.LayoutParams)
processDetailFragment.getView().getLayoutParams());
//將原fragment布局視圖從其父容器中刪除
((CoordinatorLayout) findViewById(R.id.rootview))
.removeView(processDetailFragment.getView());
//加載新的fragment
getSupportFragmentManager().beginTransaction()
.replace(R.id.rootview, fragment).commit();
//用新fragment替換原fragment的引用
processDetailFragment = fragment;
}
}
代碼運(yùn)行崎坊,新的視圖布局結(jié)構(gòu):
后記
嚴(yán)格來講,這算個(gè)偽替代洲拇,但奈揍,條條大路通羅馬!我們最終還是實(shí)現(xiàn)了我們所想所需的效果赋续,不是嗎男翰? 也因此文章標(biāo)題中的替換帶了倆引號(hào) "replace"
本文可轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處
如果這篇文章對(duì)親有所幫助纽乱,希望親可以可以給我一個(gè)小心心??蛾绎!這是對(duì)我最大的鼓勵(lì)!多謝^^
-
Windows -> Tools -> Android ->Layout Inspector 即可打開布局檢查,可以查看視圖的布局結(jié)構(gòu) ?