【问题标题】:NullPointerException when using fragment in Activity在 Activity 中使用片段时出现 NullPointerException
【发布时间】:2015-02-04 04:16:42
【问题描述】:

我的活动中有一些片段。

private MainFragment mMainFragment;
... //other fragments

这是我的 PagerAdapter。

private class MainPagerAdapter extends FragmentPagerAdapter {
    ...

    @Override
    public Fragment getItem(int position) {
        if (DEBUG) {
            Log.w(TAG, "position: " + position);
        }
        if (position == 0) {
            mMainFragment = MainFragment.newInstance(PAGE_MAIN_INDEX);
            return mMainFragment;
        } 
    }

    @Override
    public int getCount() {
        return FRAGMENT_COUNT;
    }
}

有时,当我的应用程序进入后台时,系统会终止活动,然后如果我的应用程序返回前台并且系统尝试恢复我的页面。看起来一切都很好,每个视图都正确显示。
但是当我尝试刷新我的片段时,我的应用程序崩溃了。日志显示片段为空。我不知道为什么。有什么想法吗?

这是我的 Fragment.onCreate(Bundle savedInstanceState)

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mActivity = (SubmitTenderActivity) getActivity();
    mInflater = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mResources = getResources();
}

【问题讨论】:

  • 请发布logcat

标签: android android-fragments android-viewpager


【解决方案1】:

getItem() 不会在框架恢复 Fragment 时再次被调用,因此您的 mMainFragment 在恢复后为空。 instantiateItem() 方法会为框架正在恢复的每个 Fragment 调用,因此您必须在此方法中再次重新分配 mMainFragment。更改您的代码如下应该可以解决您的问题:

private class MainPagerAdapter extends FragmentPagerAdapter {
    ...

    @Override
    public Fragment getItem(int position) {
        if (DEBUG) {
            Log.w(TAG, "position: " + position);
        }
        if (position == 0) {
            mMainFragment = MainFragment.newInstance(PAGE_MAIN_INDEX);
            return mMainFragment;
        } 
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Object obj = super.instantiateItem(container, position);
        if (position == 0) {
            mMainFragment = (MainFragment)obj;
        } 
        return obj;
    }

    @Override
    public int getCount() {
        return FRAGMENT_COUNT;
    }
}

【讨论】:

  • 但是为什么页面看起来不错。片段中的视图都正常显示。这让我很困惑。
  • 为了恢复您的应用程序,框架会创建新的 Activity 和 Fragments 实例并恢复它们保存在“savedInstanceState”中的状态。很明显,如果生成一个新的 Activity 实例但不调用 getItem() 方法,则您的 mMainFragment 为 null。
【解决方案2】:

试试这样的

 @Override
public Fragment getItem(int position) {
    switch(position){
        case 0:

            return new Fragment1();
        case 1:
            return new Fragment2();
        default:
            break;
    }

    return null;
}

【讨论】:

  • 当用户单击菜单时,我必须在我的片段中做一些事情。所以我在我的活动中保留了对 MainFragment 的强烈引用。
【解决方案3】:

最好在片段中使用以下方法:

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mActivity = activity;
    }

【讨论】:

  • 我在 Fragment.onCreate(Bundle savedInstanceState) 中这样做
  • 不要使用那种方法。这是被覆盖的方法。
  • 对不起,我不明白。我认为 onAttach 和 onCreate 都是被覆盖的方法
  • 我只在片段中重写 onCreate 和 onCreateView。我在上面发布了 onCreateView。
【解决方案4】:

我认为您应该将 return mMainFragment 从方法 getItem 中的 if 语句中移出。

【讨论】:

  • 为什么,你能给我更多的建议吗?
【解决方案5】:

你为什么不试试这个?它对我来说工作正常。

public class UpdateTabsAdapter extends FragmentPagerAdapter {
public UpdateTabsAdapter(FragmentManager fm) {
    super(fm);
}
@Override
public Fragment getItem(int index) {
    switch (index) {
    case 0:
        return new AcademicDocumentsFragment();
    case 1:
        return new EmployementDocumentsFragment();
    case 2:
        return new UploadPhotoDetailsFragment();
    }
    return null;
}
@Override
public int getCount() {
    return 3;
}
}

【讨论】:

  • 因为当用户点击菜单时我需要在我的片段中做一些事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-08
  • 2014-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多