第四章 Fragment專題

一、Fragment的第五大組件

1.Fragment的加載方式

  • 靜態(tài)加載
    直接在xml布局中添加Fragment
<fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
  • 動(dòng)態(tài)加載
    Fragment的動(dòng)態(tài)加載是由Fragment事務(wù)驅(qū)動(dòng),F(xiàn)ragment事務(wù)就是:對(duì)Fragment進(jìn)行添加、移除、替換或執(zhí)行其它動(dòng)作,提交給Activity的每一個(gè)變化;
    添加:add() 、移除:remove()、替換:replace()、提交事務(wù):commit()等方法
FragmentManager fragmentManager=getSupportFragmentManager();
fragmentManager.beginTransaction().add(new Fragment(), "TAG").commit();
fragmentManager.beginTransaction().remove(new Fragment()).commit();
// Fragment中嵌套Fragment
getChildFragmentManager().beginTransaction().remove(rescueChatFragment).commitAllowingStateLoss();

2.FragmentPagerAdapter與FragmentStatePagerAdapter

  • setOffScreenPageLimit(int limit)設(shè)置viewpager左右預(yù)加載頁(yè)
  • FragmentPagerAdapter:將每一個(gè)生成的Fragment保存在內(nèi)存中,limit外Fragment沒(méi)有銷毀,生命周期為onPause>onStop>onDestroyView,onCreateView->onStart->onResume,但Fragment的成員變量都沒(méi)有變,所以可以緩存根View,避免重復(fù)inflate
  • FragmentStatePagerAdapter:對(duì)limit外的Fragment銷毀,生命周期為onPause->onStop->onDestoryView->onDestory->onDetach, onAttach->onCreate->onCreateView->onStart->onResume。

使用場(chǎng)景:對(duì)于需要緩存在內(nèi)存中的固定較少數(shù)量的靜態(tài)頁(yè)面使用FragmentPagerAdapter,如引導(dǎo)頁(yè),Tab頁(yè)面;對(duì)于擁有大量頁(yè)面的情況應(yīng)使用FragmentStatePagerAdapter避免占用大量?jī)?nèi)存,如圖片預(yù)覽

二、Fragment的生命周期

1354170699_6619.png

三、Fragment的通訊方式

  • Fragment獲取它所在的Activity,通過(guò)getActivity()強(qiáng)制轉(zhuǎn)換調(diào)用Activity中的方法。
((HomeActivity) context).onStartProgress();
((HomeActivity) context).onStopProgressError();
  • Activity獲取它所包含的Fragment信息
// Activity中
getSupportFragmentManager().beginTransaction().add(R.id.flSpotChat, spotChatFragment).commit()
// Fragment嵌套
getChildFragmentManager().beginTransaction().add(R.id.flRescueChat, rescueChatFragment).commitAllowingStateLoss();
  • Activity想Fragment中添傳遞數(shù)據(jù)
    setArguments(Bundle bundle)
  • Fragment中定義內(nèi)部回調(diào)接口,Activity中注冊(cè)
 public interface OnSosWhoCheckListener {
        /**
         * 3:為自己呼救 1.為其他人呼救
         *
         * @param sosWho
         */
        void onCheck(String sosWho);
    }

    private OnSosWhoCheckListener onSosWhoCheckListener;

    public SpotSosDialogFragment setOnSosWhoCheckListener(OnSosWhoCheckListener onSosWhoCheckListener) {
        this.onSosWhoCheckListener = onSosWhoCheckListener;
        return this;
    }
spotSosDialogFragment = new SpotSosDialogFragment()
                .setBundle(bundle)
                .setOnSosWhoCheckListener(sosWho -> {
                    SpotFragment.this.sosWho = sosWho;
                    SpotFragment.this.sosType = "1";
                }).setOnContractListener(contractors -> {
                    SpotFragment.this.contractors = contractors;
                    SpotFragment.this.sosType = "2";
                });

四、Fragment的切換方式

1.通過(guò)fragment中的事務(wù) add(),replace(),remove()等操作
2.通過(guò)Fragment的hide(),show()來(lái)顯示
3.通過(guò)Fragment的detach()&attach()來(lái)分離Activity

區(qū)別:第一種方式是直接銷毀實(shí)例,創(chuàng)建和添加都有些影響性能,第二種是不銷毀實(shí)例和視圖,仍然占用內(nèi)存,第三種是不銷毀實(shí)例,但銷視圖,重新加載onCreateView。

五、Fragment的懶加載

1.ViewPager為什么要懶加載,什么情況適用

ViewPager的setOffScreenPageLimit()方法默認(rèn)limit為1,既會(huì)預(yù)加載左右頁(yè)面,而為了節(jié)省流量,理想情況是當(dāng)用戶切換到該界面時(shí)才會(huì)調(diào)用網(wǎng)絡(luò)請(qǐng)求獲取數(shù)據(jù)。相關(guān)方法為setUserVisibleHint(),當(dāng)前頁(yè)面為true,預(yù)加載頁(yè)面為false,只有Fragment從可見(jiàn)到不可見(jiàn)或者從不可見(jiàn)到可見(jiàn)時(shí)會(huì)調(diào)用,F(xiàn)ragment初次創(chuàng)建時(shí)setUserVisibleHint先于onCreateView()調(diào)用,所以可以由此判斷Fragment是否初始創(chuàng)建。
ViewPager首次顯示的頁(yè)面經(jīng)過(guò)方法調(diào)用
->setUserVisibleHint(false)
->setUserVisibleHint(true)
->onCreateView()...,所以該頁(yè)面的數(shù)據(jù)加載放在onCreateView中;其它預(yù)加載頁(yè)面預(yù)加載時(shí)setUserVisibleHint(false)
->onCreateView()...,當(dāng)選中該頁(yè)面顯示時(shí)調(diào)用setUserVisibleHint(true),所以預(yù)加載頁(yè)面數(shù)據(jù)加載放在setUserVisibleHint中。

2.注意事項(xiàng)

果想通過(guò)adapter.notifyDataSetChanged來(lái)刷新頁(yè)面時(shí),必須繼承FragmentStatePagerAdapter,因?yàn)镕ragmentPagerAdapter會(huì)緩存Fragment,不會(huì)走getItem方法,同時(shí)將所要刷新頁(yè)面的getItemPosition返回POSITION_NONE

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容