我在Activity上使用Action Bar。对于每个标签,我显示不同的布局。由于布局太重。所以我将每个布局充气到视图中。所以在每个标签上选择
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mView == null) {
mView = LayoutInflater.from(mAct).inflate(mLayout, null); // mAct is Activity reference
}
mAct.setContentView(mView);
for (int i = 0; i < mFrags.length; i++) {
mFrags[i] = (LutronFragment) mAct.getFragmentManager()
.findFragmentById(mIds[i]);
if (mFrags[i] != null) {
mFrags[i].setupHeader();
}
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
for (Fragment f : mFrags) {
try {
if (f != null) {
ft.remove(f);
}
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
}
所以现在,如果我第二次选择tab并在该选项卡上执行某些操作,app会在getActivity上崩溃。(NullPointerException)
请建议是否有其他方法来缓存繁重的布局。
答案 0 :(得分:38)
问题很可能是您使用的旧片段已从您的活动中分离出来。
因此,第一次创建片段时,它会附加到您的活动中。一切都很好。然后,当您更改选项卡时,您的片段可能会或可能不会与活动分离。当您回溯到它时,旧片段可能会与活动分离,因此getActivity()
将返回null。
如果您尝试保留对片段的引用,而不是通过FragmentManager
访问它们,就会发生这种情况。
如果您的适配器返回对片段的引用而不是新片段,也会发生这种情况。我陷入了这个陷阱。
(发布创建片段的代码可能有帮助)
修改强>
也许看看this以及他们如何创建添加他们的ActionBar监听器。您的活动需要范围。他们这样做的方法是在Activity / Fragment中定义监听器(通过实现接口),然后将其附加到Tab。这将为您提供范围,可能是一种更稳定的做事方式。
答案 1 :(得分:6)
如果在调用getActiviy()
的片段中创建匿名对象,则会发生这种情况。如果在片段堆栈弹出片段后,在匿名对象中调用getActivity()
,则getActivity()
将返回null。此时,片段不再与活动相关联。