Fragment使用過程中遇到過的坑

使用Fragment可以讓APP更加的流暢藕赞,并且降低內(nèi)存占用,同樣的界面Activity占用內(nèi)存比Fragment要多桑阶,相應(yīng)速度Fragment比Activity在中低端手機(jī)上快了很多悟泵。但是在Fragment的使用過程中總會出現(xiàn)一些bug,比如Fragment嵌套或者是單Activity+多Fragment架構(gòu)時鱼冀。
1.getActivity()空指針
可能你會遇到過在Fragment中使用getActivity時返回null报破,大多數(shù)情況下的原因是:你在調(diào)用了getActivity時,當(dāng)前的Fragment已經(jīng)onDetach()了宿主的Activity千绪。
解決方法:在Fragment基類里設(shè)置一個Activity mActivity的全局變量充易,在onAttach里面復(fù)制,使用mActivity代替getActivity荸型,保證Fragment即使在onDetach后盹靴,仍持有Activity引用。
protected Activity mActivity;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.mActivity = activity;
}

/**

  • 如果你用了support 23的庫瑞妇,上面的方法會提示過時稿静,有強(qiáng)迫癥的小伙伴,可以用下面的方法代替
    */
    @Override
    public void onAttach(Context context) {
    super.onAttach(context);
    this.mActivity = (Activity)context;
    }

2.Fragment重疊異常
如果你add()了幾個Fragment辕狰,使用show()改备、hide()方法控制,比如微信蔓倍、qq底部tab等場景悬钳,如果你什么都不做的話,在“內(nèi)存重啟”后回到前臺偶翅,app的這幾個Fragment界面會重疊默勾。
原因是FragmentManager幫我們管理Fragment,每當(dāng)我們離開該Activity聚谁,F(xiàn)ragmentManager都會保存它的Fragments灾测,當(dāng)發(fā)生“內(nèi)存重啟”,他會從棧低向棧頂回復(fù)Fragment垦巴,并且全部都是以show的方式,所以我們看到了界面重疊铭段。
解決方法:
(1)即在add()或者replace()時綁定一個tag骤宣,一般我們使用相應(yīng)Fragment的類名作為tag,然后在發(fā)生“內(nèi)存重啟”時序愚,通過findFragmentByTag找到相應(yīng)的Fragment憔披,并hide()需要隱藏的Fragment。
標(biāo)準(zhǔn)寫法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);

TargetFragment targetFragment;
HideFragment hideFragment;

if (savedInstanceState != null) {  // “內(nèi)存重啟”時調(diào)用
    targetFragment = getSupportFragmentManager().findFragmentByTag(targetFragment.getClass().getName);
    hideFragment = getSupportFragmentManager().findFragmentByTag(hideFragment.getClass().getName);
    // 解決重疊問題
    getFragmentManager().beginTransaction()
            .show(targetFragment)
            .hide(hideFragment)
            .commit();
}else{  // 正常時
    targetFragment = TargetFragment.newInstance();
    hideFragment = HideFragment.newInstance();

    getFragmentManager().beginTransaction()
            .add(R.id.container, targetFragment, targetFragment.getClass().getName())
            .add(R.id,container,hideFragment,hideFragment.getClass().getName())
            .hide(hideFragment)
            .commit();
}

}
如果你想恢復(fù)到用戶離開時的那個Fragment界面爸吮,你還需要在onSaveInstanceState里保存離開時的那個Fragment的tag或者下標(biāo)芬膝,在onCreate“內(nèi)存重啟”代碼中取出tag或者下標(biāo),進(jìn)行恢復(fù)形娇。
(2)使用getSupportFragmentManager.getFragments()恢復(fù)锰霜。
通過getFragments()可以獲取當(dāng)前FragmentManager管理的棧內(nèi)所有Fragment
標(biāo)準(zhǔn)寫法如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);

TargetFragment targetFragment;
HideFragment hideFragment;

if (savedInstanceState != null) {  // “內(nèi)存重啟”時調(diào)用
    List fragmentList = getSupportFragmentManager().getFragments();
    for (Fragment fragment : fragmentList) {
        if(fragment instanceof TartgetFragment){
           targetFragment = (TargetFragment)fragment;
        }else if(fragment instanceof HideFragment){
           hideFragment = (HideFragment)fragment;
        }
    }
    // 解決重疊問題
    getFragmentManager().beginTransaction()
            .show(targetFragment)
            .hide(hideFragment)
            .commit();
}else{  // 正常時
    targetFragment = TargetFragment.newInstance();
    hideFragment = HideFragment.newInstance();

    // 這里add時,tag可傳可不傳
    getFragmentManager().beginTransaction()
            .add(R.id.container)
            .add(R.id,container,hideFragment)
            .hide(hideFragment)
            .commit();
}

}
從代碼看起來這種方法比較復(fù)雜桐早,但是這種方法在一些場景下比第一種方法更加簡單有效癣缅。順便提一下厨剪,有些小伙伴會用一種并不合適的方法恢復(fù)Fragment,雖然效果也能達(dá)到友存,但并不恰當(dāng)祷膳。
// 保存
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);

getSupportFragmentManager().putFragment(outState, KEY, targetFragment);

}
// 恢復(fù)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scrolling);

if (savedInstanceState != null) {
    Fragment targetFragment = getSupportFragmentManager().getFragment(savedInstanceState, KEY);
}


如果僅僅為了找回棧內(nèi)的Fragment,使用putFragment保存Fragment是完全沒有必要的屡立。因為FragmentManager在任何情況都會把你存儲Fragment直晨,你要做的僅僅是在“內(nèi)存重啟”后找到這些Fragment。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膨俐,一起剝皮案震驚了整個濱河市勇皇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吟策,老刑警劉巖儒士,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異檩坚,居然都是意外死亡着撩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門匾委,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拖叙,“玉大人,你說我怎么就攤上這事赂乐∈眵ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵挨措,是天一觀的道長挖滤。 經(jīng)常有香客問我,道長浅役,這世上最難降的妖魔是什么斩松? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮觉既,結(jié)果婚禮上惧盹,老公的妹妹穿的比我還像新娘。我一直安慰自己瞪讼,他們只是感情好钧椰,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著符欠,像睡著了一般嫡霞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上背亥,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天秒际,我揣著相機(jī)與錄音悬赏,去河邊找鬼。 笑死娄徊,一個胖子當(dāng)著我的面吹牛闽颇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寄锐,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼兵多,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了橄仆?” 一聲冷哼從身側(cè)響起剩膘,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盆顾,沒想到半個月后怠褐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡您宪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年奈懒,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宪巨。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡磷杏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捏卓,到底是詐尸還是另有隱情极祸,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布怠晴,位于F島的核電站遥金,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蒜田。R本人自食惡果不足惜汰规,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望物邑。 院中可真熱鬧,春花似錦滔金、人聲如沸色解。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽科阎。三九已至,卻和暖如春忿族,著一層夾襖步出監(jiān)牢的瞬間锣笨,已是汗流浹背蝌矛。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留错英,地道東北人入撒。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像椭岩,于是被迫代替她去往敵國和親茅逮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容