以编程方式返回回退栈中的上一个片段

262

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

private void animateToFragment(Fragment newFragment, String tag) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(R.id.fragment_container, newFragment, tag);
    ft.addToBackStack(null);
    ft.commit();
}

如何最好地返回到之前可见的片段?

我发现在 Android 上通过按钮点击触发后退功能,但我认为模拟后退键事件并不是正确的方式(而且我也无法让它起作用):

dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));

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

有更好的方法吗?

15个回答

2
getActivity().getSupportFragmentManager().popBackStackImmediate();

或者

 getActivity().onBackPressed();

4
请阅读如何撰写一个好的答案?。虽然这个代码块可能回答了提问者的问题,但如果您解释一下这段代码与问题中的代码有何不同,您做了什么更改,为什么进行更改以及为什么这可以解决问题而不会引入其他问题,那么这个答案将更加有用。 - Saeed Zhiany

2
在最后一个片段上添加fragment_tran.addToBackStack(null),我能够回到上一个片段。 添加新的片段:
view.findViewById(R.id.changepass).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.container, new ChangePassword());
            transaction.addToBackStack(null);
            transaction.commit();
        }
    });

2

以下Kotlin代码对我很有用

1. 在简单的Activity类中添加了多个片段

override fun onBackPressed() {
    if (supportFragmentManager.backStackEntryCount > 0) {
        Log.i(TAG, "=============onBackPressed - Popping backstack====")
        supportFragmentManager.popBackStack()
    } else {
        Log.i(TAG, "=============onBackPressed called because nothing on backstack====")
        super.onBackPressed()
    }
}

2. 添加了带有多个fragment的 BottomNavigationView Activity 类

override fun onBackPressed() {

    Log.e(TAG, "=============onBackPressed")
    val navController = findNavController(R.id.nav_host_fragment)
    when (navController.currentDestination!!.id) {
        R.id.navigation_comments, R.id.navigation_my_posts -> {
            menuItemPosition = 0
            navController.navigate(R.id.navigation_home)
            Log.i(TAG, "=============onBackPressed - Popping backstack with First fragment ====")
        }
        else -> {
            Log.i(TAG, "=============onBackPressed called because nothing on backstack====")
            super.onBackPressed()
        }
    }
}

1

我来到这里寻找相同的想法,同时我也想出了自己的方法,我认为这个方法并不差,并且可以与ViewPager一起使用。

我的做法是,在持有ViewPager的父活动中覆盖onBackPressed方法,并将其设置为始终返回上一个位置,直到达到第一个片段,然后关闭活动。

@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,然后按返回会将您放在1上而不是0)。
对于我的情况,使用viewPager中的两个片段而没有选项卡,它可以很好地完成任务。

类似的问题已经有答案了。 https://dev59.com/3mgv5IYBdhLWcg3wFsyl - AtifSayings

0

尝试以下代码:

@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();
            }
        }
    }

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