安卓:碎片回退栈

39
我正在尝试在调用方法时加载一个新片段。该方法会创建一个新的片段并“替换”其他片段:

我尝试在方法被调用时加载一个新的片段。这个方法会创建一个新的片段并“替换”其他的片段:

private void showTestFragment(Fragment oldFragment, boolean addBackStack, BaseAdapter adapter, int position) {
    Cursor cursor = (Cursor)adapter.getItem(position);
    if(cursor != null){

        int idx = cursor.getColumnIndexOrThrow(Episode._ID);
        long rowId = cursor.getLong(idx);

        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        if(oldFragment != null){
            Log.i(TAG, "Removing the old fragment");
            fragmentTransaction.remove(oldFragment);
        }

        TestFragment testFragment =  new TestFragment();
        testFragment.setId(rowId);

        fragmentTransaction.add(android.R.id.content, testFragment);

        if(addBackStack){
            Log.i(TAG, "Added to the backstack");
            fragmentTransaction.addToBackStack(TAG);
        }

        fragmentTransaction.commit();
        Fragment f = getFragmentManager()
                .findFragmentById(R.id.index);
        Log.i(TAG, "after commit, frag is "+ f);
    }
}

这个很好用,直到我返回时。最后的片段应该在我返回时被删除。在我开始对这些活动实施方法之前。

public void onBackPressed(){}

我想要删除最后一个片段,但我不确定自己是否正确地处理了片段的更改。看起来我漏掉了什么...


可能是如何在Fragment中实现onBackPressed()方法?的重复问题。 - Code-Apprentice
3个回答

90

如果你真的想要替换片段,那么使用 replace () 方法而不是执行 remove () 和 add()。

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(..............);
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit(); 

不要忘记执行addToBackStack(null)方法,这样你之前的状态就会被添加到后退栈中,从而使你可以使用返回按钮返回。

另请参阅https://developer.android.com/reference/android/app/FragmentTransaction.html#replace(int, android.app.Fragment, java.lang.String)

另一个好的来源是http://developer.android.com/guide/components/fragments.html(搜索replace()函数)。


3
replace() == remove(thisFragment).add(anotherFragment)。这个等式表示replace()方法与按照上述顺序执行remove(thisFragment)和add(anotherFragment)方法的结果相同。 - Zar E Ahmer
@Nepster,没错,但并不总是方便的。FWIW,区别在于 Replace 删除容器中的任何片段; 不需要知道 thisFragment。其中一种情况是,A 片段链接到被 B1 片段替换的 B2 片段。然后,如果想要“返回”按钮返回到 A 片段(而不是 B1 片段),我们必须手动编写代码,因为 Android 的后退按钮将[错误地 IMHO]执行“删除 B1,添加 A”-与从 A 到 B1 的原始链接相反。B2 潜伏在视图后面。我们的代码必须知道 B2 是当前片段,而不是 B1。有时候这是不方便的。 - ToolmakerSteve

4

只需删除第一行并调用super.onBackPressed即可。

public void onBackPressed(){

    // here remove code for your last fragment
    super.onBackPressed();

}

0
//lets wait for systems back to finish

 super.onBackPressed();

//here we believe a fragment was popped, so we need to remove the fragment from ourbackstack
if(fragmentBackStack.size()>0)
{
    Log.d("custombackstack","before back: "+fragmentBackStack.size()+" current:"+fragmentBackStack.peek());

    fragmentBackStack.pop();            
}
//after popping is the size > 0, if so we set current fragment from the top of stack, otherwise we default to home fragment.
if(fragmentBackStack.size()>0)
{           
    Log.d("custombackstack","after back: "+fragmentBackStack.peek());
currentFragment = fragmentBackStack.peek();         
}
else
{           
    //back stack empty
    currentFragment = HOME_FRAGMENT;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接