所以我在ViewPager中有5(6?)个片段,它们都通过Activity使用回调相互交互以获取彼此之间的信息。我遇到了一些问题,因为它们需要以特定的顺序启动,有些似乎在其他人准备就绪之前就已经开始了,不管我做了什么,所以我实现了对所有片段的回调,只有在所有片段都是准备就绪:
@Override
public void notifyReady() {
boolean settingsReady = false;
boolean fileReady = false;
boolean recordTableReady = false;
boolean chartReady = false;
boolean pieChartReady = false;
if (settingsFragment != null)
settingsReady = settingsFragment.isReady();
if (fileFragment != null)
fileReady = fileFragment.isReady();
if (recordTableFragment != null)
recordTableReady = recordTableFragment.isReady();
if (chartFragment != null)
chartReady = chartFragment.isReady();
if (pieChartFragment != null)
pieChartReady = pieChartFragment.isReady();
boolean allReady = settingsReady & fileReady & recordTableReady & chartReady & pieChartReady;
if (allReady) {
settingsFragment.initialize();
fileFragment.initialize();
recordTableFragment.initialize();
chartFragment.initialize();
pieChartFragment.initialize();
}
我把接口实现放在我的FragmentPagerAdapter中,因为我在那里阅读我应该初始化片段:
@Override
public Fragment getItem(int pos) {
switch(pos) {
case 0:
return new SettingsFragment();
case 1:
return new FileFragment();
case 2:
return new OracleFragment(); // No implementation yet
case 3:
return new RecordTableFragment();
case 4:
return new ChartFragment();
case 5:
return new PieChartFragment();
default:
return null; // BAD
}
}
除了将回调接口初始化为FragmentPagerAdapter之外:
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
switch (position) {
case 0:
settingsFragment = (SettingsFragment) createdFragment;
settingsFragment.setNotificationListener(this);
break;
case 1:
fileFragment = (FileFragment) createdFragment;
fileFragment.setNotificationListener(this);
break;
case 2:
oracleFragment = (OracleFragment) createdFragment;
//oracleFragment.setNotificationListener(this); (This fragment has no implementation yet)
break;
case 3:
recordTableFragment = (RecordTableFragment) createdFragment;
recordTableFragment.setNotificationListener(this);
break;
case 4:
chartFragment = (ChartFragment) createdFragment;
chartFragment.setNotificationListener(this);
break;
case 5:
pieChartFragment = (PieChartFragment) createdFragment;
pieChartFragment.setNotificationListener(this);
break;
}
return createdFragment;
}
我的片段叫了:
public void setNotificationListener(FragmentNotifier fragmentNotifier) {
this.fragmentNotifier = fragmentNotifier;
}
表示FragmentPagerAdapter将自己设置为接口对象,
@Override
public void onStart() {
super.onStart();
ready = true;
fragmentNotifier.notifyReady();
}
用于初始化。这开始工作得非常好,但是片段注释器在一段时间后返回活动后变为null,并且当活动再次启动时调用片段'onStart(),产生NullPointerException。它为什么变成空?其他字段,比如Fragment对Activity的引用和它提供的接口在执行的这一点上都不为空,我已经用调试器检查了,但是fragmentNotifier IS!为什么呢?!
答案 0 :(得分:0)
我不会调试你的代码并找出它出错的地方,但我会给你一个更好的解决方案。
我过去经历过这一点,并且我意识到在您的Activity中定义回调的最佳方法是在Fragments中。因此,不要使用setter,而是在Fragments中使用它:
@Override
public void onAttach(Activity activity){
if (activity instanceof FragmentNotifier)
mFragmentNotifier = (FragmentNotifier) activity;
else throw new IllegalAccessException("Activity must implement the FragmentNotifier interface");
}
这将确保您可以参考您的活动。并添加此项以避免泄露引用:
@Override
public void onDetach(){
mFragmentNotifier = null;
}