Android Fragment.isAdded 从容器中移除片段后返回 true
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10715008/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fragment.isAdded returns true after fragment removed from a container
提问by vibhor
I have an activity with below layout
我有以下布局的活动
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<FrameLayout
android:id="@+id/frameLayoutA"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:id="@+id/frameLayoutB"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
</FrameLayout>
</LinearLayout>
In onCreate of activity, I load Fragment_A in frameLayoutA and Fragment_B in frameLayoutB.
在活动的onCreate 中,我在frameLayoutA 中加载Fragment_A,在frameLayoutB 中加载Fragment_B。
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
fmA=(FrameLayout) findViewById(R.id.frameLayoutA);
fmB=(FrameLayout) findViewById(R.id.frameLayoutB);
fragA=new FragmentA();
fragB=new FragmentB();
fragC=new FragmentC();
addFragmentsInActivity(R.id.frameLayoutA,fragA);
addFragmentsInActivity(R.id.frameLayoutB,fragB);
}
public void addFragmentsInActivity(int id, Fragment fragment)
{
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(id, fragment);
fragmentTransaction.commit();
}
Using a menu operation I want to load Fragment_B in frameLayoutA and Fragment_C in frameLayoutB. The Menu operation is:
使用菜单操作,我想在 frameLayoutA 中加载 Fragment_B,在 frameLayoutB 中加载 Fragment_C。菜单操作为:
removeFragmentsInActivity(R.id.frameLayoutB,fragB);
addFragmentsInActivity(R.id.frameLayoutB,fragC);
if(!fragB.isAdded()){
Log.e("check", "fragB already removed from frameLayoutB");
removeFragmentsInActivity(R.id.frameLayoutB,fragB);
addFragmentsInActivity(R.id.frameLayoutA,fragB);
}
else{
Log.e("check", "fragB already added");
}
public void removeFragmentsInActivity(int id, Fragment fragment)
{
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(fragment);
fragmentTransaction.commit();
}
Fragment_B is not displayed in frameLayoutA. frameLayoutA shows Fragment_A. When Menu operation is clicked again the Fragment_B is loaded.
Fragment_B 不显示在 frameLayoutA 中。frameLayoutA 显示 Fragment_A。当再次单击菜单操作时,Fragment_B 被加载。
Debugging I found that after fragB.isAdded() returns true after fragB.remove() operation is done. During 2nd menu operation fragB.isAdded() return false and fragB.add() is executed and FragmentB is shown in frameLayoutA.
调试我发现fragB.isAdded()在fragB.remove()操作完成后返回true。在第二个菜单操作期间 fragB.isAdded() 返回 false 并执行 fragB.add() 并且 FragmentB 显示在 frameLayoutA 中。
I understand commit is an async operation. isAdded return true because commit is async and remove operation commit is not done till the time fragB.isAdded() is called. Is it true?
我知道提交是一个异步操作。isAdded 返回 true,因为提交是异步的,并且在调用 fragB.isAdded() 之前不会完成删除操作提交。这是真的吗?
Kindly suggest the possible solution or approach to solve the issue.
请提出可能的解决方案或解决问题的方法。
Regards, Vibhor
问候, Vibhor
回答by Pawe? Nadolski
Yes the transaction is committed asynchronously. If you want to make sure all trasactions have finished before executing isAdded
, run:
是的,事务是异步提交的。如果要确保在执行之前所有交易都已完成isAdded
,请运行:
getFragmentManager().executePendingTransactions();
From documentation for executePendingTransactions()
:
从文档中executePendingTransactions()
:
After a FragmentTransaction is committed with FragmentTransaction.commit(), it is scheduled to be executed asynchronously on the process's main thread. If you want to immediately executing any such pending operations, you can call this function (only from the main thread) to do so. Note that all callbacks and other related behavior will be done from within this call, so be careful about where this is called from.
在使用 FragmentTransaction.commit() 提交 FragmentTransaction 后,它被安排在进程的主线程上异步执行。如果您想立即执行任何此类挂起操作,您可以调用此函数(仅从主线程)来执行此操作。请注意,所有回调和其他相关行为都将在此调用中完成,因此请注意从何处调用它。
So your code should look like:
所以你的代码应该是这样的:
removeFragmentsInActivity(R.id.frameLayoutB,fragB);
addFragmentsInActivity(R.id.frameLayoutB,fragC);
getFragmentManager().executePendingTransactions();
if(!fragB.isAdded()){
Log.e("check", "fragB already removed from frameLayoutB");
removeFragmentsInActivity(R.id.frameLayoutA,fragA);
addFragmentsInActivity(R.id.frameLayoutA,fragB);
}
else{
Log.e("check", "fragB already added");
}
Note also fixed removing of fragment A.
还要注意固定删除片段 A。
回答by user1611552
maybe your can encapture commition of FragmentTransaction like this
也许你可以像这样捕获 FragmentTransaction 的提交
private void commitFragmentTransaction(final FragmentTransaction ft, boolean allowStateLoss, boolean now) {
if (ft == null || ft.isEmpty()) {
return;
}
if (allowStateLoss) {
if (now) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ft.commitNowAllowingStateLoss();
} else {
ft.commitAllowingStateLoss();
mFragmentManager.executePendingTransactions();
}
} else {
ft.commitAllowingStateLoss();
}
} else {
if (now) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ft.commitNow();
} else {
ft.commit();
mFragmentManager.executePendingTransactions();
}
} else {
ft.commit();
}
}
}
commitNow() and commitNowAllowingStateLoss() is Added in API level 24
在 API 级别 24 中添加了 commitNow() 和 commitNowAllowingStateLoss()
Calling commitNow is preferable to calling commit() followed by executePendingTransactions() as the latter will have the side effect of attempting to commit all currently pending transactions whether that is the desired behavior or not.
调用 commitNow 比调用 commit() 后跟 executePendingTransactions() 更可取,因为后者将具有尝试提交所有当前挂起的事务的副作用,无论这是否是所需的行为。