2016-03-02 20 views
14

Tôi đang sử dụng đoạn ViewPager có hai đoạn như trẻ em. Đây hoạt động tuyệt vời, tuy nhiên khi tôi thay thế ViewPager đoạn bởi đoạn khác và thay thế đoạn này bằng các ViewPager mảnh treo ứng dụng của tôi với NullPointerException sau:NullPointerException khi hiển thị ViewPager lần thứ hai

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 mảnh của tôi bao gồm mã nguồn sau instanciating hai con các mảnh trong trường hợp chúng là rỗng. Hơn nữa, việc thực hiện ViewPagerAdapter được instanciated và gán cho 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); 
    } 
} 

Các ViewPagerAdapter hiển thị dưới đây thực hiện giữ tham chiếu đến các mảnh vỡ con trong một ArrayList và thực hiện các metods getItem(), getCount() cũng như getPageTitle(). Lớp ViewPagerFragment chỉ cần mở rộng lớp hỗ trợ Fragment và cung cấp phương thức trừu tượng getPageTitleStringID() được thực hiện bởi các đoạn con.

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()); 
    } 
} 

Cảm ơn sự giúp đỡ của bạn!

+0

Làm sao bạn giải quyết này? – rupinderjeet

Trả lời

6

Tôi cố định vấn đề này bằng cách đơn giản tạo ra các đoạn có chứa các xem máy nhắn tin mỗi lần tôi gọi phương thức replace của trình quản lý phân đoạn hỗ trợ.

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

Tôi đang sử dụng tài khoản của một người bạn, nhưng bạn có thể xem câu hỏi của tôi không? Tôi có ít nhiều tình hình chính xác. http://stackoverflow.com/questions/42213051/no-indication-as-to-where-npe-could-occur?noredirect=1#comment71590739_42213051 – jlively

2

Tôi nghĩ ViewPager của bạn là trong Fragment, và đoạn này đã setRetainInstance thiết lập là true (i có lỗi này quá khi tôi cố gắng giữ lại những mảnh mẹ)

+0

Xin cảm ơn! Tôi cho rằng bạn có nghĩa là tôi nên gọi 'setRetainInstance (false)'. Tôi nên gọi phương thức này ở đâu? – Lukas

0

Cách tốt hơn là để bạn có thể kiểm tra FragmentManager để có được Fragment nếu nó ở đó, nếu không sau đó tạo ra một trường hợp mới như sau:

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; 
Các vấn đề liên quan