假设我有一个以编程方式添加了片段的活动:
private void animateToFragment(Fragment newFragment, String tag) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, newFragment, tag);
ft.addToBackStack(null);
ft.commit();
}
返回上一个可见片段的最佳方法是什么?
我找到了Trigger back-button functionality on button click in Android,但我认为模拟后退键事件不是正确的方法(我也无法让它工作):
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
致电finish()
只会关闭我不感兴趣的活动。
有没有更好的方法来解决这个问题?
答案 0 :(得分:321)
查看getFragmentManager().popBackStack()
方法(有几种方法可供选择)
http://developer.android.com/reference/android/app/FragmentManager.html#popBackStack()
答案 1 :(得分:119)
详细说明提供的其他答案,这是我的解决方案(放在活动中):
@Override
public void onBackPressed(){
FragmentManager fm = getFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
Log.i("MainActivity", "popping backstack");
fm.popBackStack();
} else {
Log.i("MainActivity", "nothing on backstack, calling super");
super.onBackPressed();
}
}
答案 2 :(得分:24)
当我们更新/添加片段时,
应包括.addToBackStack()
。
getSupportFragmentManager().beginTransaction()
.add(detailFragment, "detail") // Add this transaction to the back stack (name is an optional name for this back stack state, or null).
.addToBackStack(null)
.commit();
之后,如果我们提供getFragments.popBackStackImmediate()
将返回true,如果我们添加/更新片段,然后返回当前屏幕。
答案 3 :(得分:8)
将这些行添加到onBackPressed()方法中。如果后端堆栈上有任何片段,popBackStackImmediate()方法将返回到上一个片段 `
if(getFragmentManager().getBackStackEntryCount() > 0){
getFragmentManager().popBackStackImmediate();
}
else{
super.onBackPressed();
}
`
答案 4 :(得分:4)
当您想要在主片段中按下后关闭应用时,此解决方案非常适用于基于底部条的片段导航。
另一方面,当您打开我的代码中定义为“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();
答案 5 :(得分:2)
如果我没有在片段事务中添加addToBackStack(),这些答案将不起作用,但是,您可以使用:
getActivity().onBackPressed();
从您的任何片段返回上一步;
答案 6 :(得分:1)
使用以下代码以编程方式返回上一个片段。
if ( getFragmentManager().getBackStackEntryCount() > 0)
{
getFragmentManager().popBackStack();
return;
}
super.onBackPressed();
答案 7 :(得分:1)
要使该片段再次出现,只需将该片段添加到您想要返回的背板上,例如:
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
时打开Button button
,此时用户位于SignupFragment
。因此,如果addToBackStack(TAG)
被调用,TAG = "SignupFragment"
,那么当在LoginFragment
中按下后退按钮时,我们会回到SignUpFragment
。
快乐的编码!
答案 8 :(得分:1)
我来这里的目的或想法是相同的,与此同时,我想出了自己的想法,我认为这还不错,并且可以与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,然后按回车,则可能效果不佳)将您置于1,而不是0)
对于我来说,在viewPager中有2个不带制表符的片段,它做得很好。
答案 9 :(得分:1)
2020年7月16日-Kotlin回答
使用Kotlin在Android Studio 4.0中进行编码:
fragmentManager?.popBackStack()
祝您编程愉快!
@canerkaseler
答案 10 :(得分:1)
Android Studio 4.0.1 Kotlin 1.3.72
Android导航架构组件。
以下代码对我有用:
findNavController().popBackStack()
答案 11 :(得分:0)
通过在最后一个片段上添加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();
}
});
答案 12 :(得分: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();
}
}
}
答案 13 :(得分:0)
以下对我有用的Kotlin代码
1.在使用多个片段的简单活动类中添加
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.在 BottomNavigationView 使用多个片段的活动类中添加
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()
}
}
}