【发布时间】:2015-05-16 16:12:01
【问题描述】:
我有一个应用程序,其主屏幕有 2 个片段(目前)和一个导航抽屉。目前我在启动时加载片段 A(探索)并在单击时加载片段 B。从那时起,我展示和隐藏片段。它比每次点击都重新创建片段要快,而且我的片段 A 需要一些时间来加载。
我注意到,当我转到片段 B 并从那里转到另一个活动(我们称之为活动 2)并离开应用程序并等待它被杀死(或做一些疯狂的事情,比如更改设备语言) ,然后回到相同的活动,它仍然存在。当我按返回返回片段 B 时,有时(50% 的时间)片段 B 被绘制在片段 A 上。单击抽屉中的片段 A 时,片段 A 看起来很好,但单击片段 B 时,还有另一个实例片段 A 和片段 B 的顶部。
我在这个问题上花了超过 2 天的时间,却一无所获。
这是我选择片段的代码:
private void selectItem(int position, boolean addExploreFragment) {
Log.d(tag, "selectItem: " + position);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
//add explore fragment - this is called on app startup, but also when the app is killed and resumed which results in 2 explore fragments
if (addExploreFragment){
fragmentTransaction.replace(R.id.content_frame, mExploreFragment, EXPLORE_FRAGMENT_TAG);
Log.d(tag, "Replaced frame and added "+ mFragmentTags[position]);
} else {
//add fragment for the first time
if (getSupportFragmentManager().findFragmentByTag(mFragmentTags[position]) == null && position != 0) {
fragmentTransaction.add(R.id.content_frame, mFragments[position], mFragmentTags[position]);
Log.d(tag, "Added Fragment: "+ mFragmentTags[position]);
}
//shows and hides fragments
for (int i = 0; i < mFragments.length; i++) {
if (i == position) {
fragmentTransaction.show(mFragments[i]);
Log.d(tag, "Showing Fragment: "+ mFragmentTags[i]);
} else {
if (getSupportFragmentManager().findFragmentByTag(mFragmentTags[i]) != null) {
fragmentTransaction.hide(mFragments[i]);
Log.d(tag, "Hid Fragment: "+ mFragmentTags[i]);
}
}
}
}
fragmentTransaction.commit();
//not null check for calling selectItem(0) before loading the drawer
if (mDrawerList != null){
mDrawerList.setItemChecked(position, true);
}
}
我确定,探索片段被创建了两次,并且这两个实例的行为彼此独立(只是共享)。
我不知道下一步该做什么。这是一个在低端设备上很容易重现的问题,但在像 Nexus 4(我的测试设备)这样的设备上,可以通过更改设备语言来重现该问题。
有人对此有任何想法吗?基本上,如果 addExploreFragment 块在已经存在 exploreFragment 时没有被调用,我认为这个问题可以解决,但我一直无法这样做。此外,我尝试删除所有片段,然后添加 exploreFragment 但同样的事情发生(50% 的时间)。
谢谢!很抱歉这篇长文,我觉得我应该分享所有细节。
更新:当我更改设备语言并返回 Activity 2 上的应用程序并返回 Home Activity 时,它打开了片段 B,这很好,但片段 A 被重新创建,因为这是一个沉重的碎片,系统可能会将其从内存中删除。同样,如果系统将其删除,则可以重新创建它,但是为什么在未删除它时会重新创建它。我相信这与我的代码有关,每次第二次尝试(不关闭应用程序)都会发生这种情况,重片段 A 的 2 个实例。没有想法。
但是不应该fragmentTransaction.replace 删除所有之前添加的片段,然后添加exploreFragment。它不是那样工作的。片段 A 和片段 B 都没有被删除。
【问题讨论】:
-
是的,但是您仍然错过了一些细节,Fragment A 是如何声明的?静态方式?也就是说,它是按名称在 xml 中声明的吗?如果是,您创建了两个实例。还有你在哪里切换
addExploreFragment?。 -
@Elltz 不,所有片段都是动态创建并添加到框架布局中的。 addExploreFragment 仅在应用启动时为真。在其他任何地方,调用 selectItem 时都设置为 false。所以基本上,当添加探索片段时。这是一个多余的参数,现在我想起来了。
-
如果我理解正确,在 MainActivity 中调用了 selectItem()。在生命周期的上下文中,它调用了哪些覆盖方法?我一直盯着代码,这是我看到的唯一问题。
-
@TheOriginalAndroid 它在 onCreate 上调用,addExploreFragment 设置为 true。除此之外,在 DrawerItemClickListener 中的 onItemClick 中调用来切换 Fragment,addExploreFragment 设置为 false。
-
我同意您在 onCreate 中的代码。我确实发布了答案。
标签: android android-fragments fragmenttransaction