在FragmentPagerAdapter中,getItemPosition(Object object)默認實現會將傳入的Fragment對象強制轉換為特定類型。當ViewPager包含多種Fragment子類時,調用notifyDataSetChanged()觸發此方法導致ClassCastException。
@Override
public int getItemPosition(Object object) {
FragmentPage2 f = (FragmentPage2) object; // 危險:假設所有Fragment都是FragmentPage2
if (f != null) f.update();
return super.getItemPosition(object);
}
當getItem()返回FragmentPage1實例時,上述強轉拋出異常:FragmentPage1 cannot be cast to FragmentPage2。
@Override
public int getItemPosition(Object object) {
if (object instanceof FragmentPage2) {
((FragmentPage2) object).update();
} else if (object instanceof FragmentPage1) {
((FragmentPage1) object).update();
}
// 返回POSITION_UNCHANGED表示位置未變,避免重建
return POSITION_UNCHANGED;
}
定義公共接口,所有Fragment實現:
public interface UpdatableFragment {
void update();
}
public class FragmentPage1 extends Fragment implements UpdatableFragment { ... }
public class FragmentPage2 extends Fragment implements UpdatableFragment { ... }
Adapter中統一調用:
@Override
public int getItemPosition(Object object) {
if (object instanceof UpdatableFragment) {
((UpdatableFragment) object).update();
}
return POSITION_UNCHANGED;
}
private List fragments = new ArrayList<>();
// getItem中從列表獲取或創建
@Override
public Fragment getItem(int position) {
while (fragments.size() <= position) fragments.add(null);
if (fragments.get(position) == null) {
fragments.set(position, createFragment(position));
}
return fragments.get(position);
}
// 更新時直接遍歷列表
public void updateAllFragments() {
for (Fragment f : fragments) {
if (f instanceof UpdatableFragment) ((UpdatableFragment) f).update();
}
}
POSITION_UNCHANGED:Fragment位置未變,ViewPager保留實例,僅調用setUserVisibleHint等生命周期。POSITION_NONE:Fragment已移除,ViewPager銷毀並重建。動態增減頁面時對應位置返回此值。getItemPosition中強制轉型具體Fragment類。POSITION_NONE觸發重建。FragmentStateAdapter(ViewPager2)自動處理生命周期。