我有一个主屏幕的应用程序,它有2个片段(现在)和导航抽屉。目前我在启动时加载片段A(Explore)并在单击时加载片段B.从那时起,我展示并隐藏片段。它比在每次点击时重新创建片段更快,而我的片段A需要一些时间来加载。
我注意到当我去片段B并从那里去另一个活动(让它称之为活动2)并离开应用程序并等待它被杀死(或做一些疯狂的事情)比如改变设备语言,然后再回到相同的活动,它仍然在那里。当我按回去回到片段B时,有时(50%的时间)片段B被绘制在片段A上。在抽屉中单击片段A时,片段A看起来很好,但是在点击片段B时,有'片段A的另一个实例,在片段B的顶部。
我已经花了两天多时间解决这个问题并且无处可去。
这是我选择片段的代码:
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%的时间)。
谢谢!对于长篇文章感到抱歉,我觉得我应该分享所有的细节。
更新:当我更改设备语言并返回活动2上的应用程序并返回主页活动时,它打开了片段B,这很好,但片段A重新创建,因为它是一个沉重的片段,系统可能会从内存中删除它。再说一遍,如果它被系统删除,它会被重新创建,但为什么在它没有被删除时重新创建它。我相信它是我的代码的一部分,在每次第二次尝试(没有关闭应用程序)这发生时,重型片段A的2个实例。出于想法。
但不应该使用fragmentTransaction.replace删除之前添加的所有片段,然后添加exploreFragment。它不是那样工作的。片段A和片段B都没有被删除。
答案 0 :(得分:1)
我发现了一些新的东西而且对我来说很奇怪。当您使用fragmentTransaction.add
时,上一个片段上的侦听器(如上一个片段)仍处于活动状态。即使您使用fragmentTransaction.commit
。
所以......我怀疑当使用 add 方法时,你实际上点击了另一个隐藏的按钮或隐藏的UI,它在前一个片段上有一个事件监听器。我当然不喜欢这样,效果可能非常混乱。是的,这发生在我身上,我暂时不理解为什么。
目前,我认为最简单的代码修复方法是使用替换方法而不是添加。 replace()使侦听器处于非活动状态。如果它有效,那么你可以做出更好/更优雅的修复。
让我知道会发生什么......
答案 1 :(得分:0)
我开始注意到你的帖子了
当我去片段B然后去另一个活动时
当您进行交互或启动另一个活动时,您将启动一组新的碎片。请查看此Google网页@ Fragments Lifecycle。 为了澄清我的说法,有一句话说
片段必须始终嵌入到活动和片段中 生命周期直接受主机活动生命周期的影响。
你至少可以阅读它的几个段落。
我不确定你的解决方案应该是什么。也许在你所拥有的两项活动之间使片段与众不同,不同和清晰。