[英]Fragment Backstack
Hi I have an activity and three fragments. 嗨,我有一个活动和三个片段。 When I replace my first fragment I am adding it to backstack.
当我替换我的第一个片段时,我将它添加到backstack中。
FragmentTransaction fragmentTransaction = getFragmentManager()
.beginTransaction();
fragmentTransaction.replace(R.id.authentication_parent0_linear,
new LoginFragment(), LOGINTAG);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
But when I move between the other two fragments I am not adding them to backstack.So whenever I press back from the other two fragments I need to go back to first fragment.It works fine when I remove first fragment and add second fragment or remove first and add third ie when I press back I am coming back to first fragment. 但是当我在另外两个片段之间移动时,我没有将它们添加到backstack中。所以每当我从其他两个片段按回来时,我需要回到第一个片段。当我删除第一个片段并添加第二个片段或删除时它工作正常首先添加第三个,即当我按下时,我将回到第一个片段。 But when I navigate between those two fragments that is remove second and add third or remove third and add second etc .
但是当我在这两个片段之间导航时,会删除第二个并添加第三个或删除第三个并添加第二个等。 At that instance when I press back I am exiting the app and backstackcount is shown as zero but for the first time when I removed the first fragment I stored it in the backstack.
在那个例子,当我按下我退出应用程序并且backstackcount显示为零但是我第一次删除第一个片段时将其存储在backstack中。
getFragmentManager()
.beginTransaction()
.replace(R.id.authentication_parent0_linear,
new SignupFragment(), SIGNUPTAG).commit();
So my question is will the fragment backstack resets between commits. 所以我的问题是片段backstack会在提交之间重置。 If so how can I get the stored fragment in the backstack for the first time
如果是这样,我怎样才能第一次在后台堆叠中获取存储的片段
Best way to achieve what you want is not to use fragment's backstack. 实现你想要的最好方法是不使用fragment的backstack。
addToBackStack()
anywhere addToBackStack()
Keep your first fragment LoginFragment
reference in the instance field mLoginFragment. 在实例字段mLoginFragment中保留第一个片段
LoginFragment
引用。 Addition of your first fragment will look like this (probably in activity's onCreate()
: 添加第一个片段将如下所示(可能在activity的
onCreate()
:
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); mLoginFragment = new LoginFragment(); fragmentTransaction.replace(R.id.authentication_parent0_linear, mLoginFragment, LOGINTAG); fragmentTransaction.commit();
in your activity override onBackPressed()
method as following: 在您的活动中重写
onBackPressed()
方法如下:
@Override public void onBackPressed() { Fragment fr = getFragmentManager().findFragmentById(R.id.authentication_parent0_linear); // chek that mLoginFragment!=null, basically this should never happen! if (fr == mLoginFragment) { super.onBackPressed(); } else { FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.authentication_parent0_linear, mLoginFragment, LOGINTAG); fragmentTransaction.commit(); } }
There is a cumbersome way to achieve the desired effect with the use of backstack. 使用背板可以通过一种麻烦的方式来达到预期的效果。 Here is how:
方法如下:
addToBAckStack()
when creating fragment A addToBAckStack()
addToBackStack()
addToBackStack()
When navigating deeper from B to C, etc. call popBackStack()
before the transaction. 当从B更深地导航到C等时,在事务之前调用
popBackStack()
。 Explanation of it can be found on SO. 可以在SO上找到它的说明。 Like this:
像这样:
getFragmentManager().popBackStack(); FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.authentication_parent0_linear, new FragmentC(), "whatever"); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit();
The Fragment manager allows you to put a Name (or TAG) on a given state. 片段管理器允许您将名称(或TAG)放在给定状态。 If you pass that same name to popBackStack it will pop states until it reaches that state.
如果将相同的名称传递给popBackStack,它将弹出状态直到达到该状态。 For example
例如
// Add initial fragment
getFragmentManager()
.beginTransaction();
.replace(R.id.authentication_parent0_linear, new LoginFragment());
.addToBackStack(TAG_FIRST_FRAGMENT_STATE) // The key is not passing null here
.commit();
// Add other fragments like such
getFragmentManager()
.beginTransaction();
.replace(R.id.authentication_parent0_linear, new SignupFragment());
.addToBackStack(null)
.commit();
// On back press
@Override
public void onBackPressed() {
FragmentManager fragmentManager = getFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 1) {
fragmentManager.popBackStack(TAG_FIRST_FRAGMENT_STATE, 0);
} else {
super.onBackPress();
}
}
I fnally figured it out. 我最终想通了。 based on Kirill K answer
基于Kirill K答案
public class MainActivity extends Activity implements OnClickAuthentication,
LoginInterface, SignupInterface {
FragmentManager fragmentManager;
FragmentTransaction fragmentTransaction;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag("one");
if (fragment == null) {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction
.replace(R.id.relative, new OneFragment(), "one");
fragmentTransaction.commit();
}
}
@Override
public void onClickAuthButton(int flag) {
if (flag == 2) {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction
.replace(R.id.relative, new TwoFragment(), "two");
fragmentTransaction.commit();
} else {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.relative, new ThreeFragment(),
"three");
fragmentTransaction.commit();
}
}
@Override
public void switchToSignup() {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction
.replace(R.id.relative, new ThreeFragment(), "three");
fragmentTransaction.commit();
}
@Override
public void switchToLogin() {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.relative, new TwoFragment(), "two");
fragmentTransaction.commit();
}
@Override
public void onBackPressed() {
Fragment twoFragment = fragmentManager.findFragmentByTag("two");
Fragment threeFragment = fragmentManager.findFragmentByTag("three");
if ((twoFragment != null && twoFragment.isVisible())
|| (threeFragment != null && threeFragment.isVisible())) {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction
.replace(R.id.relative, new OneFragment(), "one");
fragmentTransaction.commit();
} else {
super.onBackPressed();
}
}
} }
I have done it like this 我这样做了
FragmentManager fm = getFragmentManager();
fm.beginTransaction().replace(R.id.content_frame , new main_fragment()).commit();
void replaceFragment (Fragment fragment) {
Fragment current = fm.findFragmentById(R.id.content_frame);
//Check if that frag is already opened
if (!current.getClass().equals(fragment.getClass())) {
String backStateName = fragment.getClass().getName();
boolean fragmentPopped = fm.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped) {
//fragment is not in back stack,so add it.
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();
}
}
else {
//if fragmentPopped is true then it will auto pop up the fragment
//so we dnt have to do anything here
}
}
replaceFragment(new yourfragment());
public void onBackPressed() {
int backStackEntryCount = fm.getBackStackEntryCount();
if (backStackEntryCount == 0) {
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Closing Activity")
.setMessage("Are you sure you want to close this Application?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
System.exit(0);
}
})
.setNegativeButton("No", null)
.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
//backpress over alert dialog
finish();
System.exit(0);
}
})
.show();
} else {
super.onBackPressed();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.