2016-03-02 17 views
14

2つのフラグメントを子として持つViewPagerフラグメントを使用しています。これは私が別のフラグメントでViewPager断片を置換して、次のNullPointerExceptionViewPagerフラグメントによって自分のアプリケーションがクラッシュし、この断片を置換ただし際に、素晴らしい作品:ViewPagerを2度目に表示すると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フラグメントは2子をinstanciating次のソースコードで構成されていそれらが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子フラグメントへの参照を保持し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

(私は親の断片を保持しようとすると、私はあまりにも、このエラーが発生している)がtrueに設定されています私はサポートフラグメントマネージャーの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私は単に含む断片を作成することで問題を修正

+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; 
関連する問題