getargument - fragment layout in android




使用碎片清除棧 (8)

只需使用此方法並將Context&Fragment標記傳遞到我們需要刪除後台碎片的地方。

用法

clearFragmentByTag(context, FragmentName.class.getName());



public static void clearFragmentByTag(Context context, String tag) {
    try {
        FragmentManager fm = ((AppCompatActivity) context).getSupportFragmentManager();

        for (int i = fm.getBackStackEntryCount() - 1; i >= 0; i--) {
            String backEntry = fm.getBackStackEntryAt(i).getName();
            if (backEntry.equals(tag)) {
                break;
            } else {
                 fm.popBackStack();
            }
        }
    } catch (Exception e) {
        System.out.print("!====Popbackstack error : " + e);
        e.printStackTrace();
    }
}

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

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


我在這裡發布類似的東西

來自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)

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


我只是想補充一點: -

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

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。


我這樣工作:

public void showHome() {
    getHandler().post(new Runnable() {
        @Override
        public void run() {
            final FragmentManager fm = getSupportFragmentManager();
            while (fm.getBackStackEntryCount() > 0) {
                fm.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)

為@ Warpzit的評論作出回答,並使其他人更容易找到...使用:

fragmentManager.popBackStack(null, 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(); }

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

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

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




android-fragments