Android:片段 backStack

Posted

技术标签:

【中文标题】Android:片段 backStack【英文标题】:Android: Fragments backStack 【发布时间】:2012-12-30 13:32:01 【问题描述】:

我试图在调用方法时加载新片段。此方法创建一个新片段并“替换”另一个片段:

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()

要删除最后一个片段,我想知道我是否正确处理了片段更改。看来我在这里遗漏了一些东西..

【问题讨论】:

How to implement onBackPressed() in Fragments?的可能重复 【参考方案1】:

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

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

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

另见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() 函数)。

【讨论】:

replace() == remove(thisFragment).add(anotherFragment).. replace 等于这两个方法的顺序。 @Nepster,是的,但并不总是很方便。 FWIW,不同之处在于 Replace 删除容器中的任何片段;不需要知道thisFragment。这很重要的一种情况是,如果片段 A 链接到片段 B1,而片段 B1 被片段 B2 替换。那么如果想要“返回”按钮返回到 Fragment A(而不是 B1),我们必须手动编写代码,因为 Android 的返回将 [不正确地恕我直言] 执行“删除 B1,添加 A” - 与原始链接相反从 A 到 B1。 B2 潜伏在后面。我们的代码必须知道 B2 是当前片段,而不是 B1。有时这很不方便。【参考方案2】:

只需先删除,然后调用 super.onBackPressed

public void onBackPressed()

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


【讨论】:

【参考方案3】:
//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;

【讨论】:

以上是关于Android:片段 backStack的主要内容,如果未能解决你的问题,请参考以下文章

数据从父片段传递到选项卡片段(子) - Android

Android - 选项卡式片段

Android片段中的问题:仍然单击上一个片段

如何从Android中的片段单击按钮打开片段

Android:片段 backStack

Android:将“ViewPager”动画从片段更改为片段