【问题标题】:FragmentManager is null after creating Fragment创建 Fragment 后 FragmentManager 为空
【发布时间】:2016-10-12 01:01:40
【问题描述】:

我的问题是,在创建一个新的Fragment 后,它的FragmentManager 在我的ViewPager 中设置为当前项目时有时是null。 换句话说,这会导致ViewPagersetCurrentItem() 中出现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


【解决方案1】:

您可能应该让类为您创建片段,无需将片段存储在列表中。

private final String[] categories = {"cat1", "cat2", "cat3"};
private final String[] titles = {"category 1", "category 2", "category 3"};
public class PagerAdapter extends FragmentPagerAdapter {

  public PagerAdapter(FragmentManager fm) {
    super(fm);
  }

  @Override
  public int getCount() {
    return categories.length;
  }

  @Override
  public Fragment getItem(int position) {
    return PostsFragment.newInstance(categories[position]);
  }

  @Override
  public CharSequence getPageTitle(int position) {
    return titles[position];
  }
}

然后当你切换位置时会自动创建片段。

【讨论】:

    猜你喜欢
    • 2020-02-06
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    • 2014-03-01
    • 1970-01-01
    相关资源
    最近更新 更多