当前位置: 首页 > 知识库问答 >
问题:

ViewPager和动态片段:re-instaciation提供NPE

漆雕修德
2023-03-14

我在Android中遇到了ViewPager和ViewPagerAdapter的问题。我使用一个带有两个静态片段的viewpager(一个使用textEdit,第二个使用listview)。他们工作得很好。但我对第三个片段有一个问题,它是动态的。它使用相机,必须在一个场景下被实例化、销毁、重新实例化。因此,ViewPagerAdapter可以包含2或3个框架。当我重新安装第三个片段时,问题出现了,我在OnCreateView()之后得到了一个NPE(主布局视图在这个方法之后是null,但在方法内部不是null)。

主要活动的代码如下:

    mViewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager();
    mTabLayout = (TabLayout) findViewById(R.id.tabs);
    mTabLayout.setupWithViewPager(mViewPager);
private void setupViewPager() {
    mViewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
    mTabFragmentDocument = new TabFragmentDocument();
    mTabFragmentDocument.setApp(this);
    mTabFragmentText = new TabFragmentText();
    mTabFragmentText.setApp(this);

    mViewPagerAdapter.addFragment(mTabFragmentText, AbstractDefiner.TEXT);
    mViewPagerAdapter.addFragment(mTabFragmentDocument, AbstractDefiner.DOCUMENT);
    mViewPager.setAdapter(mViewPagerAdapter);
}
                mTabFragment = new TabFragment();
                mTabFragment .setApp(this);
                mViewPagerAdapter.addFragment(mTabFragment, "THIRD");
                mViewPagerAdapter.notifyDataSetChanged();
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mViewPager.setCurrentItem(2);
                        mViewPagerAdapter.notifyDataSetChanged();
                        mTabFragment .setParams(tmp[1], tmp[2], tmp[3], tmp[4]);
                        mTabFragment .setupView();
                        mTabFragment .startWork();
                    }
                }, 1000);
                mViewPager.setCurrentItem(0);
                mViewPager.removeViewAt(2);
                mTabFragment .onDestroy();
                mViewPagerAdapter.remove(2);
                mViewPagerAdapter.notifyDataSetChanged();
                mTabFragment = null;

然后,适配器代码:

static class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    public void remove(int index) {
        mFragmentList.remove(index);
        mFragmentTitleList.remove(index);
    }

    @Override
    public int getItemPosition(Object object) {
        return PagerAdapter.POSITION_NONE;
    }


    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}

最后,第三个片段的代码:

public class TabFragment extends Fragment implements SurfaceHolder.Callback,
    GLSurfaceView.Renderer {

private static final String LOGCAT = "WEB_RTC_VISIO";

private HomeActivity mApp;
private String p1;
private String p2;
private String p3;
private String p4;

private VideoSource mLocalVideoSource;
private VideoRenderer.Callbacks mLocalRenderer;
private VideoRenderer.Callbacks mRemoteRenderer;
private GLSurfaceView mVideoView;
private SurfaceView mDrawView;
private SurfaceHolder mDrawHolder;
private ImageView mCursor;
private String mBgBytesString;
private ImageView mImgView;

private View mV;

public TabFragment() {
    // Required empty public constructor
}

public void setApp(HomeActivity app) {
    mApp = app;
}

public void setParams(String p1, String p2, String p3,
                      String p4) {
    this.p1= p1;
    this.p2= p2;
    this.p4= p4;
    this.p3= p3;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    mV = inflater.inflate(R.layout.third_layout, container, false);
    return mV;
}

@Override
public void onDetach() {
    super.onDetach();

}

public void setupView() {
    RequestUserPermission requestUserPermission = new RequestUserPermission(mApp);
    requestUserPermission.verifyStoragePermissions();
    mImgView = (ImageView) mV.findViewById(R.id.img_display); // NPE HERE
    TextView mTest1= (TextView) mV.findViewById(R.id.test1);
    mRequestLabelTextView.setText("test 1");
    TextView mTest2= (TextView) mV.findViewById(R.id.test2);
    mEquipmentSerialTextView.setText("test 2");
    // View that displays the view from the camera
    mVideoView = (GLSurfaceView) mV.findViewById(R.id.gl_surface);
    // View that displays the cursor and drawing associated
    mDrawView = (SurfaceView) mV.findViewById(R.id.draw_surface);
    mDrawHolder = mDrawView.getHolder();
    mDrawHolder.setFormat(PixelFormat.TRANSPARENT);
    mDrawHolder.addCallback(this);
    // Image of the cursor
    mCursor = (ImageView) mV.findViewById(R.id.mouseCursor);
    // Some more inits
}
public void startWork() {
//SOME WORK
}
}

所以,第一个实例是可以的,但在第二个实例中,我在获得ImageView时得到了NPE...有人能帮我理解这个问题吗?

提前感谢!

共有1个答案

赵英范
2023-03-14

尝试使用FragmentStatePagerAdapter而不是FragmentPagerAdapter,它将解决许多问题。希望这对你也有用。

 类似资料:
  • 我想在一个Android应用程序中使用3个片段,ired:creating-and-using-fragmentpageradapter。但是我想使用viewpager来滑动和显示片段,就像在:ViewPager-with-FragmentPagerAdapter中解释的那样。但是这个代码或者Android Studio示例的默认代码,每次需要时使用newInstance创建实例,不需要时销毁。

  • 在我的应用程序中,我有标签的活动(让我们说10个标签)。每个选项卡页都包含和(此ListView中显示的数据是从我的服务器动态加载的)。我使用来显示这些页面。我不想将所有保存在内存中,所以我决定使用(我的适配器类扩展了这些类)。 > 假设选择了第三个选项卡。然后,当我转到第一个选项卡时,应该从头开始为该选项卡创建(这很好,这就是的工作方式),但不恢复该片段以前的状态(例如,不应该滚动到上次访问该时

  • 问题内容: 片段对于将UI逻辑分为一些模块来说似乎非常好。但是随着它的生命周期,我仍然迷茫。因此,非常需要大师的想法! 编辑 请参阅下面的愚蠢解决方案;-) 范围 主要活动有一个带有片段。这些片段可以为其他(子主)活动实现一些不同的逻辑,因此片段的数据通过活动内部的回调接口填充。并且所有功能在首次启动时都正常,但是! 问题 重新创建活动时(例如,在方向更改时),的片段也是如此。代码(您将在下面找到

  • 我需要扩展的。它没有错误,但当我试图在适配器中调用它时。 基本上,我需要显示片段B上的所有事件。如果我在没有片段的情况下测试它,它可以工作,但有了它们,它就成了一个小问题。我需要这些片段,因为用于滑动。 片段B代码: CustomListAdapter代码:公共类CustomListAdapter扩展BaseAdapter{private Activity;private LayoutInflat

  • 如何限制我的主要活动不返回片段的最后一页,一旦从片段的最后一页返回到主要活动,就像我有一个主活动一样,单击按钮,该主活动会导致另外3个活动,其中一个活动有片段。片段的最后一页指向home activity,但当我在home activity上后退时,它再次将我引导到片段的最后一页,然后我再次按下back按钮,然后我的应用程序关闭 我的主要活动课 公共类主页扩展应用程序活动{ } 我零星的寻呼机 公

  • 我似乎不明白为什么在设置适配器后片断是空的,但是如果我把片断更新代码放在单击事件中,我就没有问题了。