编辑2
我现在设法通过使用来自此处https://code.google.com/p/android/issues/detail?id=42601#c10的技巧摆脱了错误,这就是我最后一次编辑放在我的问题上的原因。
但这导致了下一个错误:
java.lang.NullPointerException
at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:569)
at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:211)
at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1281)
at android.view.View.dispatchRestoreInstanceState(View.java:12043)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2688)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2694)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2694)
at android.view.View.restoreHierarchyState(View.java:12021)
at android.support.v4.app.Fragment.restoreViewState(Fragment.java:425)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:949)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4800)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:798)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:565)
at dalvik.system.NativeStart.main(Native Method)
现在我不知道从哪里继续......
编辑0 - 第一个问题
我得到以下例外:
java.lang.IllegalStateException: No activity
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1091)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1877)
at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1492)
at android.support.v4.app._HoloFragment.performActivityCreated(_HoloFragment.java:251)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4800)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:798)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:565)
at dalvik.system.NativeStart.main(Native Method)
我不知道从哪里开始。我正在使用最新的支持库(v4,rev18)。
一切正常,直到我添加一个Fragment
,其中ViewPager
与FragmentStatePagerAdapter
结合使用。
我到处都在使用支持库,我尝试了https://code.google.com/p/android/issues/detail?id=42601 ...
的解决方案但是没有任何效果......
我不知道从哪里开始,有人有提示吗?
编辑1:背景和代码
1)在我的MainActivity中,我使用以下内容:
第三页有viewpager ......
public void setPage(int pos, boolean addToBackStack)
{
Fragment nextFragment = null;
FragmentTransaction transaction = null;
switch (pos)
{
case 0:
if (mFragmentAllRoutines == null)
mFragmentAllRoutines = new RoutinesListFragment();
if (!mFragmentAllRoutines.isVisible())
nextFragment = mFragmentAllRoutines;
break;
case 1:
if (mFragmentRoutine == null)
mFragmentRoutine = new RoutineFragment();
if (!mFragmentRoutine.isVisible())
nextFragment = mFragmentRoutine;
break;
case 2:
if (mFragmentDay == null)
mFragmentDay = new RoutineDayFragment();
if (!mFragmentDay.isVisible())
nextFragment = mFragmentDay;
break;
default:
break;
}
if (nextFragment != null)
{
// Fragment prevFragment = getSupportFragmentManager().findFragmentById(R.id.fragment);
transaction = getSupportFragmentManager().beginTransaction();
// if (prevFragment != null)
// transaction.detach(prevFragment);
transaction.replace(R.id.fragment, nextFragment, nextFragment.getClass().getName());
// transaction.attach(nextFragment);
if (addToBackStack)
transaction.addToBackStack(null);
transaction.commit();
}
}
2)第三个片段:
这是一个带有ViewPager和FragmentStatePagerAdapter的简单片段。 FragmentStatePagerAdapter得到getChildFragmentManager()
作为FragmentManager。在某个地方似乎存在问题。
答案 0 :(得分:67)
我需要查看更多代码才能知道在哪里应用这个...但我遇到了类似的情况......我以同样的方式解决了ChildFragmentManager
问题,并得到了同样的结果NullPointerException
,就像你一样。
我确实设法解决了......我会尝试描述我的解决方案,就像你提供的代码一样,我不确定在哪里应用“修复”...这真的是一个修复......这不是解决这个问题的优雅方式!然而它确实帮助了我,一旦我离开视图寻呼机,我就不需要恢复状态了,所以对我来说没有任何不利因素。
我有多个片段,它们实现代码的静态位和onDetach(on https://code.google.com/p/android/issues/detail?id=42601#c10),每个片段都有一个寻呼机,onCreateView我附加了一个扩展FragmentStatePagerAdapter的适配器。
在那些适配器上我已经覆盖了restoreState方法什么都不做
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
//do nothing here! no call to super.restoreState(arg0, arg1);
}
同样,这不是最好的方式......但确实解决了我的问题。
祝你好运!
答案 1 :(得分:12)
我偶然发现了同样的问题。
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:873)
at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:215)
Marc的解决方案有效,但在我的情况下,它使用FragmentStatePagerAdapter在Fragment上造成了滞后。所以我覆盖了restoreState,名为super,将它包装在try / catch中,它没有滞后。
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
try{
super.restoreState(state, loader);
}catch (NullPointerException e){
// null caught
}
}
更新:
从那时起,我就一直在使用这种解决方案。所以使用它是安全的。
答案 2 :(得分:1)
就我而言,我在一个包含片段中保留了对ViewPager片段的引用,并使用onSaveInstanceState来存储它们的状态。 我认为NPE的发生是因为它与ViewPager自己的机制发生冲突以恢复碎片。我做了什么,将我的架构从ViewPager更改为我自己管理的片段事务。 (ViewPager不适合我的情况)
答案 3 :(得分:0)
首先,英语不是我的母语,如果我的语法有问题,请告诉我。 我在我的项目中遇到了这个问题。起初我做了Marc所说的,而且效果很好。但是当我在父片段中添加另一个ViewPager时,新的ViewPager显示与旧的ViewPager相同,无论这个新的viewpager中有什么样的代码。 最后我发现了原因。我们总是使用FragmentTrasaction.replace(R.layout.fragment,fragment)方法创建Fragment。因此,我们在使用此方法时会创建一个新的片段实例。我使用FragmentTransaction.hide()和show()方法来切换片段,而不是使用replace()方法。我这样解决了我的问题。 这是我的代码片段:
@Override
public void onClick(View v) {
FragmentTransaction transaction = fm.beginTransaction();
switch (v.getId()) {
case R.id.tv_schedule_day:
hideFragment(transaction);
if (dayFragment == null) {
dayFragment = new ScheduleDayFragment();
transaction.add(R.id.ll_schedule_content, dayFragment);
} else {
transaction.show(dayFragment);
}
transaction.commit();
break;
case R.id.tv_schedule_week:
hideFragment(transaction);
if (weekFragment == null) {
weekFragment = new ScheduleWeekFragment();
transaction.add(R.id.ll_schedule_content, weekFragment);
} else {
transaction.show(weekFragment);
}
transaction.commit();
break;
case R.id.tv_schedule_month:
hideFragment(transaction);
if (monthFragment == null) {
monthFragment = new ScheduleMonthFragment();
transaction.add(R.id.ll_schedule_content, monthFragment);
} else {
transaction.show(monthFragment);
}
transaction.commit();
break;
private void hideFragment(FragmentTransaction transaction) {
if (dayFragment != null) {
transaction.hide(dayFragment);
}
if (weekFragment != null) {
transaction.hide(weekFragment);
}
if (monthFragment != null) {
transaction.hide(monthFragment);
}
}
我使用hide()和show()方法来创建切换父片段,所以当我在嵌入片段中使用getChildFragmentManager()时,它不会返回null。 这个问题在2013年被问到,我想没有人会看到这个答案,但我仍然很高兴回答这个问题。