ViewPager随着时间的推移碎片被破坏?

我正在使用Android的support.v4包来开发包含多个Fragment的ViewPager。

我想在用户更改页面时隐藏视图。 所以,我实现了一个OnPageChangeListener来监听我的适配器,并在发生页面更改时调用我的Fragmentupdate()方法。 但是我得到一个NullPointerException ,我不明白为什么。

这里是代码:

 public class MyActivity extends FragmentActivity implements OnPageChangeListener { private static final int NUM_ITEMS = 2; private ViewPager mPager; private static SpaceAdapter mAdapter; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_pager); mAdapter = new SpaceAdapter(getSupportFragmentManager()); mPager = (ViewPager) findViewById(R.id.pager); mPager.setAdapter(mAdapter); mPager.setOnPageChangeListener(this); } public static class SpaceAdapter extends FragmentPagerAdapter { public SpaceAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return NUM_ITEMS; } @Override public Fragment getItem(int position) { switch (position) { case 0: return new MyFragment(); case 1: return new MyFragment(); default: return new MyFragment(); } } } @Override public void onPageScrollStateChanged(int arg0) { Log.i("pagination", "scroll state changed: " + arg0); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { // Log.i("pagination", "page scroll: " + arg0 + " with: " + arg1 + ", " + arg2); if (mAdapter.getItem(arg0) instanceof IUpdateOnPage) { ((IUpdateOnPage) mAdapter.getItem(arg0)).updateOnPage(); } } @Override public void onPageSelected(int arg0) { Log.i("pagination", "page selected: " + arg0); } } 

 public class MyFragment extends Fragment implements SurfaceHolder.Callback, IUpdateOnPage { private SurfaceView charts; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.crew, null); bindViews(v); return v; } private void bindViews(View v) { charts = (SurfaceView) v.findViewById(R.id.civ_charts); charts.getHolder().addCallback(this); Log.i("wtf", "huh " + String.valueOf(charts == null)); // logs false } @Override public void updateOnPage() { if (charts != null) { Log.i("crew surface", "hidden"); charts.setVisibility(View.GONE); } else { Log.i("crew surface", "charts is null"); //THIS HERE gets logged } } } 

当我复制/粘贴我删除了SurfaceHolder.Callback方法,但他们在那里。 bindViews(v)方法loggingcharts == null ,并始终返回false。 当我页面, updateOnPage被调用,并且charts == null返回true。 为什么会发生这种情况,我该如何解决这个问题?

这是第108行:

 charts.setVisibility(View.GONE); 

Solutions Collecting From Web of "ViewPager随着时间的推移碎片被破坏?"

初始化ViewPager时添加以下ViewPager

 mPager.setOffscreenPageLimit(NUM_ITEMS-1); 

在你的情况下,这将设置离屏页面的数量为1(即,当另一页面当前处于焦点时,它将保持附加的离屏页面在内存中)。 这将迫使你的ViewPager保留所有的Fragment即使它们不是焦点。

我检查了你的代码,我认为问题是在onPageScrolled ,你调用getItem 。 这个实现(实际上就像Web上的大多数实现)每次都返回一个新的实例。 然而,我见过的大多数例子都没有调用getItem ,所以这通常是正常的。

在你的情况下,我会持久地在getItem创buildFragment:如果它不存在于那个位置,然后创build它,然后将它挂在ArrayList或其他集合中,但是如果它已经存在,只需返回它从那个集合。

否则,你创build一个片段实例A,然后滚动到另一个片段实例B.你试图告诉片段实例A来清理一些视图,但是你告诉一个新的片段实例C来做这个。 它还没有机会build立自己的视图,所以你得到空指针图表。