Android 以编程方式返回backbackback中的上一个片段

Android 以编程方式返回backbackback中的上一个片段,android,android-fragments,back-stack,Android,Android Fragments,Back Stack,假设我有一个以编程方式添加片段的活动: private void animateToFragment(Fragment newFragment, String tag) { FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(R.id.fragment_container, newFragment, tag); ft.addToBackStack(null); f

假设我有一个以编程方式添加片段的活动:

private void animateToFragment(Fragment newFragment, String tag) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_container, newFragment, tag);
    ft.addToBackStack(null);
    ft.commit();
}
返回到之前可见片段的最佳方式是什么

我发现,但我认为模拟一个back key事件不是正确的方法(我也无法让它工作):

调用
finish()
只会关闭我不感兴趣的活动


有更好的方法吗?

看看
getFragmentManager().popbackbackstack()
方法(有几种方法可供选择)


要详细说明提供的其他答案,这是我的解决方案(放置在活动中):


当我们更新/添加片段时

应包括
.addToBackStack()


然后,如果我们给出
getFragments.popbackackimmediate()
将返回true,如果我们添加/更新片段,并返回到当前屏幕。

使用以下代码以编程方式返回到上一个片段

if ( getFragmentManager().getBackStackEntryCount() > 0) 
{
          getFragmentManager().popBackStack();
          return;
}
super.onBackPressed();

将这些行添加到onBackPressed()方法中。如果在后堆栈上有任何片段,popbackbackimmediate()方法将使您返回到上一个片段 `


`

当您想在主片段中按下后关闭应用程序时,此解决方案非常适用于基于底部栏的片段导航

另一方面,当您打开在我的代码中定义为“DetailedPizza”的次要片段(片段中的片段)时,它将返回主片段的先前状态。干杯

背面的内部活动按下此按钮:

Fragment home = getSupportFragmentManager().findFragmentByTag("DetailedPizza");

if (home instanceof FragmentDetailedPizza && home.isVisible()) {
    if (getFragmentManager().getBackStackEntryCount() != 0) {
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
} else {
    //Primary fragment
    moveTaskToBack(true);
}
然后像这样发射另一个碎片:

Fragment someFragment = new FragmentDetailedPizza();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container_body, someFragment, "DetailedPizza");
transaction.addToBackStack("DetailedPizza");
transaction.commit();

若要使该碎片再次出现,只需将该碎片添加到您希望再次按下的backbackback,例如:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Fragment fragment = new LoginFragment();
        //replacing the fragment
        if (fragment != null) {
            FragmentTransaction ft = ((FragmentActivity)getContext()).getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.content_frame, fragment);
            ft.addToBackStack("SignupFragment");
            ft.commit();
        }
    }
});
在上述情况下,当按下
按钮时,我正在打开
LoginFragment
,此时用户处于
SignupFragment
中。因此,如果调用了
addToBackStack(TAG)
,其中
TAG=“SignupFragment”
,那么当在
LoginFragment
中按下后退按钮时,我们返回到
SignupFragment


快乐编码

通过在最后一个片段上添加
fragment\u tran.addToBackStack(null)
,我可以在最后一个片段上返回

添加新片段:

请尝试以下代码:

@Override
    public void onBackPressed() {
        Fragment myFragment = getSupportFragmentManager().findFragmentById(R.id.container);
        if (myFragment != null && myFragment instanceof StepOneFragment) {
            finish();
        } else {
            if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                getSupportFragmentManager().popBackStack();
            } else {
                super.onBackPressed();
            }
        }
    }

如果我没有将addToBackStack()添加到片段事务中,则这些答案无效,但是,您可以使用:

getActivity().onBackPressed();

从你的任何碎片回到一步

我来这里的目的是为了寻找相同的想法,同时我提出了自己的想法,我相信这并不坏,如果使用ViewPager,它会起作用

所以我所做的,是覆盖父活动中保存viewPager的onBackPressed方法,并将其设置为始终返回负1位置,直到到达第一个片段,然后关闭活动

@Override
public void onBackPressed() {
    if(viewPager.getCurrentItem()>0){
        viewPager.setCurrentItem(viewPager.getCurrentItem()-1);
    } else {
        super.onBackPressed();
        this.close();
    }
}

private void close(){
    this.finish();
}
这可能有一个缺点,就像每次只返回左一个方向一样,因此如果有选项卡,并且您切换位置时跳过了片段,则效果可能不太好(从0到2,然后按back会将您设置为1,而不是0)


对于我的例子tho,在viewPager中有两个片段,没有选项卡,它很好地完成了工作

Kotlin回答

  • 首先,调用片段管理器
  • 之后,使用onBackPressed() 方法
  • 使用Kotlin在Android Studio 4.0中编码:

    fragmentManager?.popBackStack()
    

    Android导航架构组件。

    以下代码适用于我:

    findNavController().popBackStack()
    

    getFragmentManager()成功了。谢谢。不过我该把这个方法放在哪里呢?在我的tab listener?没有看到代码,很难说。。。但是,当您想“关闭”当前片段并返回到上一个片段时,它应该在代码中执行。getSupportFragmentManager()如何?别忘了在代码中添加“addToBackStack(“tag”)”。“fragmentManager.beginTransaction().replace(R.id.content_frame,fragment).addToBackStack(“标记”).commit();”如果您编写addToBackStack(null),它将自行处理,但如果您提供标记,则应手动处理。为什么会发生这种情况。在片段示例中,它们并没有过度隐藏onbackpressed事件,但它们能够对片段进行回退。我使用了trasaction.addToBackStack(null);但什么也没发生。你能解释一下原因吗?@MurtazaHussain如果你想得到帮助,你可能应该问一个新问题。如果不看更多的代码,就很难看到发生了什么。在我的例子中,我必须执行
    fm.getbackbackbackentrycount()>1
    ,以便在堆栈中只有第一个片段时调用该活动。Android已经为您做了以下操作:“当后台堆栈上有FragmentTransaction对象且用户按下“后退”按钮时,FragmentManager会从后台堆栈中弹出最新的事务并执行反向操作(例如,如果事务添加了一个片段,则删除该片段)。“我认为,标签不会影响,它甚至可能是空的。类似的问题已经得到了回答<代码>requireActivity().onBackPressed()
    用于Kotlin当您使用自定义设计的工具栏时,此方法非常方便。如果你正在使用navController,我想你必须使用这种方法-我首先尝试了片段管理器(上面的答案),后来尝试使用navController导航时遇到了故障。
    @Override
        public void onBackPressed() {
            Fragment myFragment = getSupportFragmentManager().findFragmentById(R.id.container);
            if (myFragment != null && myFragment instanceof StepOneFragment) {
                finish();
            } else {
                if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                    getSupportFragmentManager().popBackStack();
                } else {
                    super.onBackPressed();
                }
            }
        }
    
    getActivity().onBackPressed();
    
    @Override
    public void onBackPressed() {
        if(viewPager.getCurrentItem()>0){
            viewPager.setCurrentItem(viewPager.getCurrentItem()-1);
        } else {
            super.onBackPressed();
            this.close();
        }
    }
    
    private void close(){
        this.finish();
    }
    
    fragmentManager?.popBackStack()
    
    findNavController().popBackStack()