android getargument 使用碎片清除棧




fragment layout in android (10)

我將我的Android應用程序移植到蜂窩中,並且為了使用碎片而做了一個大的重構。 在我之前的版本中,當我按下主頁按鈕時,我用來執行ACTIVITY_CLEAR_TOP以重置回棧。

現在我的應用程序只是一個具有多個片段的Activity,所以當我按下Home按鈕時,我只是替換其中的一個片段。 如何清除我的後退堆棧而無需使用帶有ACTIVITY_CLEAR_TOP標誌的startActivity


private boolean removeFragFromBackStack() {
    try {
        FragmentManager manager = getSupportFragmentManager();
        List<Fragment> fragsList = manager.getFragments();
        if (fragsList.size() == 0) {
            return true;
        }
        manager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

我在這裡發布類似的東西

來自Joachim的回答,來自Dianne Hackborn:

http://groups.google.com/group/android-developers/browse_thread/thread/d2a5c203dad6ec42

我結束了使用:

FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {    
    fm.popBackStack();
}

但同樣可以使用類似的東西:

FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)

這將彈出所有狀態到指定的狀態。 然後你可以用你想要的來替換片段


閱讀documentation並研究片段ID是什麼,它看起來只是堆棧索引,所以這是有效的:

fragmentManager.popBackStackImmediate(0, FragmentManager.POP_BACK_STACK_INCLUSIVE);

零( 0 )是堆棧的底部,所以彈出它(包括它)將清除堆棧。

CAVEAT:儘管上面的程序在我的程序中有效,但我有點猶豫,因為FragmentManager文檔從未實際指出id是堆棧索引。 它是有道理的,而且我的所有調試日誌都是完整的,但也許在某些特殊情況下它不會呢? 任何人都可以確認這種方式嗎? 如果是這樣,那麼以上是最好的解決方案。 如果不是,這是另一種選擇:

while(fragmentManager.getBackStackEntryCount() > 0) { fragmentManager.popBackStackImmediate(); }

清除沒有循環的backstack

String name = getSupportFragmentManager().getBackStackEntryAt(0).getName();
getSupportFragmentManager().popBackStack(name, FragmentManager.POP_BACK_STACK_INCLUSIVE);

其中name是addToBackStack()參數

getSupportFragmentManager().beginTransaction().
                .replace(R.id.container, fragments.get(titleCode))
                .addToBackStack(name)

我這樣工作:

public void showHome() {
    getHandler().post(new Runnable() {
        @Override
        public void run() {
            final FragmentManager fm = getSupportFragmentManager();
            while (fm.getBackStackEntryCount() > 0) {
                fm.popBackStackImmediate();
            }
        }
    });
}

適用於我而不使用循環的簡單方法:

 FragmentManager fragmentManager = getSupportFragmentManager();
 //this will clear the back stack and displays no animation on the screen
 fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

我只是想補充一點: -

使用以下內容從後台堆棧彈出

fragmentManager.popBackStack()

只是從事務中刪除碎片,沒有辦法從屏幕上刪除碎片。 因此,理想情況下,它可能對您而言不可見,但可能會有兩個或三個碎片堆疊在一起,並且在後退按鍵時,UI可能看起來很雜亂,堆疊。

舉一個簡單的例子: -

假設你有一個使用fragmentmanager.replace()加載Fragmnet B的fragmentA ,然後我們使用addToBackStack來保存這個事務。 所以流量是: -

第1步 - > FragmentA-> FragmentB(我們移動到FragmentB,但片段A在後台,不可見)。

現在你在fragmentB中做一些工作,然後按下Save按鈕 - 保存後應該返回到fragmentA。

步驟2->在保存FragmentB時,我們回到FragmentA。

第3步 - >所以常見的錯誤是......在片段B中,我們將片段Manager.replace()與片段A進行片段化。

但實際發生的是,我們再次加載碎片A,替換FragmentB。 所以現在有兩個FragmentA(一個來自STEP-1,另一個來自這個STEP-3)。

碎片A的兩個實例堆疊在一起,可能不可見,但它在那裡。

因此,即使我們通過上述方法清除了backstack,事務也被清除了,但不是實際的碎片。 因此理想情況下,在這種特殊情況下,只需按fm.popBackStack()fm.popBackImmediate()就可以返回到fragmentA。

所以正確的Step3-> fm.popBackStack()返回已經在內存中的fragmentA。


接受的答案是不夠的。 我不得不使用:

FragmentManager fm = getSupportFragmentManager();
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {
    fm.popBackStackImmediate();
}

充分尊重所有相關方; 我很驚訝地看到你們有多少人可以用簡單的方法清除整個碎片堆棧

fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

根據Android文檔 (關於name參數 - 聲明的工作提案中的“null”)。

如果為null,則只彈出頂部狀態

現在,我意識到我對你的特定實現缺乏了解(比如在給定的時間點你有多少條條目),但是我希望我所有的錢都能在接受的答案上下注,更廣泛的設備和供應商的行為:

(供參考,與此一起)

FragmentManager fm = getFragmentManager(); // or 'getSupportFragmentManager();'
int count = fm.getBackStackEntryCount();
for(int i = 0; i < count; ++i) {    
    fm.popBackStack();
}

    private void clearBackStack(){
        SupportFragmentManaer fm = getSupportFragmentManager();
        fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

呼叫這個方法會非常整齊。

  1. 無需循環。
  2. 如果您在片段中使用動畫,則不會顯示太多動畫。 但使用循環會。




android-fragments