【发布时间】:2016-10-12 01:01:40
【问题描述】:
我的问题是,在创建一个新的Fragment 后,它的FragmentManager 在我的ViewPager 中设置为当前项目时有时是null。
换句话说,这会导致ViewPager 的setCurrentItem() 中出现NullPointerException,因为它引用了片段的FragmentManager。
我第一次执行以下代码时,FragmentManager 几乎从不为空(但添加打印语句有时会改变该行为),并且由于 FragmentManager 为空,它总是在第二次崩溃。
Fragment fragment = PostsFragment.newInstance( some_string_params );
int position = pager_adapter.addFragment( fragment );
Log.i( "MY_TAG", fragment.getFragmentManager() ); //sometimes null !!!!!
view_pager.setCurrentItem( position ); //internal NullPointerException
Fragment 似乎仍在后台设置,只是没有及时准备好使用。我该如何解决这个问题?
编辑:
这是我的FragmentPagerAdapter:
public class PagerAdapter extends FragmentPagerAdapter
{
private final FragmentManager fragment_manager;
private final List<Fragment> fragments = new ArrayList<>();
public PagerAdapter( FragmentManager manager )
{
super( manager );
this.fragment_manager = manager;
}
public int addFragment( Fragment fragment )
{
fragments.add( fragment );
notifyDataSetChanged();
return fragments.size() - 1;
}
public void pop()
{
int index = getCount() - 1;
Fragment fragment = fragments.remove( index );
FragmentTransaction transaction = fragment_manager.beginTransaction();
transaction.remove( fragment );
transaction.commit();
fragment_manager.executePendingTransactions(); //execute the commit synchronously
notifyDataSetChanged();
}
@Override
public int getCount()
{
return fragments.size();
}
@Override
public Fragment getItem( int position )
{
return fragments.get( position );
}
}
堆栈跟踪:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.FragmentManagerImpl.performPendingDeferredStart(android.support.v4.app.Fragment)' on a null object reference
at android.support.v4.app.FragmentPagerAdapter.setPrimaryItem(FragmentPagerAdapter.java:130)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1175)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:608)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:570)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:551)
at fragments.CategoryActivityFragment.onCategoryClicked(CategoryActivityFragment.java:56)
at adapters.CategoriesAdapter$1.onClick(CategoriesAdapter.java:84)
at android.view.View.performClick(View.java:5207)
at android.view.View$PerformClick.run(View.java:21168)
at android.os.Handler.handleCallback(Handler.java:746)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
【问题讨论】:
-
您能提供更多代码吗?实例化我在 FragmentPagerAdapter 类中覆盖 getItem 的片段。
-
@JohnathonHavens 您到底想看什么?到目前为止,我发布的 sn-p 在
View.OnClickListener内部非常孤立,它附加到几个代表类别的按钮上。所以我单击一个按钮,执行该代码以创建片段并使用ViewPager切换到它。至于我的addFragment()方法,它只是将片段添加到LinkedList并调用notifyDataSetChanged()。 -
我只是想看看你的扩展
FragmentPagerAdapter的类是如何定义的,当我使用寻呼机时,它通常与TabLayout串联选择其他页面或通过滑动进行更改。调用setCurrentItem时的堆栈跟踪是什么? -
@JohnathonHavens 我添加了扩展 FragmentPagerAdapter 和堆栈跟踪的类。
-
您为什么不在适配器中创建片段?例如在
getItem(position)中,您可以检查需要生成什么类型的片段,然后根据该类型返回片段的类型。我觉得,你的代码不是使用 FragmentPagerAdapter 的最佳方式
标签: android android-fragments nullpointerexception fragmentmanager