2016-03-02 71 views
14

我正在使用ViewPager片段,它有两个片段作为子对象。这个伟大的工程,但是当我通过另一个片段与以下NullPointerException更换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的片段由下面的源代码instanciating两个孩子片段,如果它们为空。此外,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的参照子片段和实现metods 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()); 
    } 
} 

感谢您的帮助!

+0

你是怎么解决这个问题? – rupinderjeet

回答

6

我只需创建一个包含片段固定的问题每次我打电话给支持片段管理器的方法replace时,查看寻呼机。

public void onSwitchToConnectionPasswordGenerator(View clickedView) 
{ 
    this.fragConnectionPassword = new ConnectionPasswordViewPagerFragment(); 
    this.getSupportFragmentManager().beginTransaction().replace(R.id.flFragmentContainer, this.fragConnectionPassword).commitAllowingStateLoss(); 
} 
+0

我正在使用朋友的帐户,但可以看看我的问题吗?我有或多或少的确切情况。 http://stackoverflow.com/questions/42213051/no-indication-as-to-where-npe-could-occur?noredirect=1#comment71590739_42213051 – jlively

2

我想你Viewpager是片段,而这个片段已经setRetainInstance设置为true(我有这个错误太当我尝试保持母体片段)

+0

谢谢!我想你的意思是我应该调用'setRetainInstance(false)'。我应该在哪里调用这个方法? – Lukas

0

更好的方法是你可以检查FragmentManager如果得到碎片它的存在,如果没有则创建一个新的实例如下:

FragmentManager manager = getSupportFragmentManager(); 
Fragment fragment = manager.findFragmentByTag("YourFragmentName"); 

if(fragment == null) 
    fragment = new YourFragment(); 

FragmentTransaction fragmentTransaction = manager.beginTransaction(); 
fragmentTransaction.replace(Your_Fragmnet_Container_Layout_id, fragment, fragment.getClass().getSimpleName()); 
fragmentTransaction.commit; 
相关问题