切換Fragment避免重複載入
阿新 • • 發佈:2019-02-10
現在市面上很多手機應用都會有一個非常類似的功能,就是螢幕下方有一行Tab標籤選項,點選不同的標籤就可以切換到不同的介面:
這樣就可以避免每次切換都重新建立Fragment了,很簡單吧,但是還有個問題,有時候我們切換的時候需要處理一些事情,比如剛開始是未登入狀態,現在登入了,切換頁面時要更新一些資料,那怎麼辦呢?Fragment裡有個onHiddenChanged方法,是專門用來處理Fragment顯示與隱藏的事件的。
這個在以前是用ActivityGroup(年代太久遠了,那時候俺還木有畢業呢0.0),因為Fragment的種種優勢和其靈活性,現在官方推薦的替代方法是用Fragment。
使用Fragment的話,我之前是先通過getSupportFragmentManager(),再beginTransaction()開啟事務,FragmentTransaction中有add(),replace(),remove()三個方法,我之前是用replace方法每次替換掉之前的Fragment,但是我們會發現,使用replace()時,每次切換,Fragment都會重新建立,這樣就比較不好了。從網上搜索發現可以通過show和hide方法避免重複載入(借鑑了郭霖大神的思路,但是他的方式在我的app裡會出現重影)。So我換了一種實現方式。當然本質沒有區別,還是通過一次將所有的Fragment新增到一個集合裡,再通過隱藏和顯示完成的。
佈局檔案還是RadioGroup巢狀RadioButton,程式碼隨便看看就好啦
FrameLayout作為容器裝載Fragment,這裡簡單做三個Fragment就好了,就不放程式碼了。然後該初始化的初始化,該findViewById的findViewById,然後也是開啟個事務,把我們的幾個Fragment新增到一個ArrayList中。PagerOne,PagerTwo,PagerThree就是我們說的三個Fragment。<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.v_lzhiy.tablayout.HideFragmentActivity"> <FrameLayout android:id="@+id/fl_container" android:layout_width="match_parent" android:layout_height="match_parent"/> <RadioGroup android:id="@+id/radioGroup" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#f9f9f9" android:gravity="center_horizontal" android:orientation="horizontal" android:padding="5dp" > <RadioButton android:id="@+id/pager1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@android:color/transparent" android:button="@android:color/transparent" android:drawableTop="@drawable/rb_me_selector" android:textSize="18sp" android:textColor="@drawable/bottom_radiobutton_selector" android:drawablePadding="1dp" android:gravity="center" android:text="Home"/> <RadioButton android:id="@+id/pager2" style="@style/BottomRadioButton" android:text="探索" android:drawableTop="@drawable/rb_me_selector"/> <RadioButton android:id="@+id/pager3" style="@style/BottomRadioButton" android:text="我" android:drawableTop="@drawable/rb_me_selector"/> </RadioGroup> </LinearLayout>
fragmentManager = getSupportFragmentManager(); fragmentTransaction = fragmentManager.beginTransaction(); fragments = new ArrayList<>(); pagerOne = new PagerOne(); pagerTwo = new PagerTwo(); pagerThree = new PagerThree(); fragments.add(pagerOne); fragments.add(pagerTwo); fragments.add(pagerThree); fragmentTransaction.add(R.id.fl_container,pagerOne); fragmentTransaction.add(R.id.fl_container,pagerTwo); fragmentTransaction.add(R.id.fl_container,pagerThree);
再把三個Fragment新增到FragmentTransaction中,是add不是replace哦。這樣,我們就可以通過我們選擇不同的Radiobutton通過顯示與隱藏的方式切換Fragment了,但是在這之前,我們還要做一件事,三個Fragment都新增進去了,會出現重影……需要我們手動設定進入app時要顯示哪一頁,其餘的隱藏。我這裡是顯示第一頁:
radioGroup.check(R.id.pager1);
fragmentTransaction.show(pagerOne).hide(pagerTwo).hide(pagerThree);
fragmentTransaction.commit();
這樣就顯示了第一頁,隱藏了其餘兩頁。當我們切換RadioButton時,再顯示該顯示的隱藏其餘的,switchFragment(int index)就是顯示與隱藏的控制程式碼。
radioGroup.setOnCheckedChangeListener(new NestRadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(NestRadioGroup group, int checkedId) {
switch(checkedId){
case R.id.pager1:
switchFragment(0);
break;
case R.id.pager2:
switchFragment(1);
break;
case R.id.pager3:
switchFragment(2);
break;
}
}
});
}
/**
* 選擇隱藏與顯示的Fragment
* @param index 顯示的Frgament的角標
*/
private void switchFragment(int index){
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
for(int i = 0; i < fragments.size(); i++){
if (index == i){
fragmentTransaction.show(fragments.get(index));
}else {
fragmentTransaction.hide(fragments.get(i));
}
}
fragmentTransaction.commit();
}
這樣就可以避免每次切換都重新建立Fragment了,很簡單吧,但是還有個問題,有時候我們切換的時候需要處理一些事情,比如剛開始是未登入狀態,現在登入了,切換頁面時要更新一些資料,那怎麼辦呢?Fragment裡有個onHiddenChanged方法,是專門用來處理Fragment顯示與隱藏的事件的。
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden){
//隱藏
}else {
//顯示,更新資料
}
}
恩,這樣就沒毛病了。