我使用的ViewPager片段有两个片段作为孩子.这样做非常好,但是当我用另一个片段替换ViewPager片段,并且通过ViewPager片段替换此片段时,我的应用程序会使用以下NullPointerException:
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:667) at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:211) at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1319) at android.view.View.dispatchRestoreInstanceState(View.java:13756) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2888) at android.view.View.restoreHierarchyState(View.java:13734) at android.support.v4.app.Fragment.restoreViewState(Fragment.java:468) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1094) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5294) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
我的ViewPager片段包含以下源代码,用于实现两个子片段,以防它们为null.此外,ViewPagerAdapter实现被实例化并分配给ViewPager.
public class ConnectionPasswordViewPagerFragment extends Fragment { private ViewPager vpConnectionPassword; private ConnectionPasswordViewPagerAdapter paConnectionPassword; private ConnectionPasswordGeneratorMACAddress passwordGeneratorMACAddress; private ConnectionPasswordGeneratorSerialNumber passwordGeneratorSerialNumber; public ConnectionPasswordViewPagerFragment() { // required empty public constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if ((this.passwordGeneratorSerialNumber == null) && (this.passwordGeneratorMACAddress == null)) { this.passwordGeneratorMACAddress = new ConnectionPasswordGeneratorMACAddress(); this.passwordGeneratorSerialNumber = new ConnectionPasswordGeneratorSerialNumber(); } } @Override public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_connection_password_view_pager,container,false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); /*if (this.paConnectionPassword == null) {*/ this.paConnectionPassword = new ConnectionPasswordViewPagerAdapter(this.getChildFragmentManager(),this.getActivity(),this.passwordGeneratorMACAddress,this.passwordGeneratorSerialNumber); //} this.vpConnectionPassword = (ViewPager) this.getActivity().findViewById(R.id.vpConnectionPassword); this.vpConnectionPassword.setAdapter(this.paConnectionPassword); } }
下面显示的ViewPagerAdapter将保留对ArrayList中的子片段的引用,并实现getItem(),getCount()以及getPageTitle(). ViewPagerFragment类简单地扩展了支持Fragment类,并提供了由子片段实现的抽象方法getPageTitleStringID().
public class ConnectionPasswordViewPagerAdapter extends FragmentStatePagerAdapter { private static final byte NUMBER_OF_FRAGMENTS = (byte) 2; private ArrayList<ViewPagerFragment> childFragments; private Activity displayActivity; public ConnectionPasswordViewPagerAdapter(FragmentManager fragmentMgm,Activity displayAct,ConnectionPasswordGeneratorMACAddress generatorMACAddress,ConnectionPasswordGeneratorSerialNumber generatorSerialNumber) { super(fragmentMgm); this.childFragments = new ArrayList<>(ConnectionPasswordViewPagerAdapter.NUMBER_OF_FRAGMENTS); this.setDisplayActivity(displayAct); if (generatorMACAddress != null) { this.childFragments.add(generatorMACAddress); } if (generatorSerialNumber != null) { this.childFragments.add(generatorSerialNumber); } } public Activity getDisplayActivity() { return this.displayActivity; } public void setDisplayActivity(Activity value) { this.displayActivity = value; } @Override public Fragment getItem(int position) { return this.childFragments.get(position); } @Override public int getCount() { return ConnectionPasswordViewPagerAdapter.NUMBER_OF_FRAGMENTS; } @Override public CharSequence getPageTitle(int position) { return this.getDisplayActivity().getString(this.childFragments.get(position).getPageTitleStringID()); } }
谢谢你的帮助!
解决方法
我通过在每次调用支持片段管理器的替换方法时创建包含视图寻呼机的片段来解决问题.
public void onSwitchToConnectionPasswordGenerator(View clickedView) { this.fragConnectionPassword = new ConnectionPasswordViewPagerFragment(); this.getSupportFragmentManager().beginTransaction().replace(R.id.flFragmentContainer,this.fragConnectionPassword).commitAllowingStateLoss(); }