0

J'essaie d'ajouter un ViewPager à mon application Android comme un écran de configuration unique pour l'utilisateur. Mais le problème que je suis confronté est que l'application continue de s'écraser lorsque l'orientation de l'écran est changé parmi le processus d'installation.Android ViewPager se bloque avec NullPointerException sur le changement d'orientation

Si l'application est ouverte en mode portrait ou paysage et utilisée sans changement d'orientation, elle fonctionne correctement. Mais si l'orientation est modifiée pendant l'exécution, l'utilisation de la méthode setCurrentItem(int position) sur le ViewPager bloque l'application.

Voilà ma Fragment classe -

package com.cosine.arc; 


import android.content.Context; 
import android.graphics.Typeface; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.view.ViewPager; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.TextView; 

/** 
* A simple {@link Fragment} subclass. 
*/ 
public class WelcomeFragment extends Fragment { 

private int mPosition; 
private Context mContext; 
private ViewPager mPager; 

private final int[] welcomeFragments = {R.layout.fragment_welcome1}; 

public WelcomeFragment() { 
    // Required empty public constructor 
} 

public WelcomeFragment(Context context, ViewPager viewPager, int position) { 

    this.mPosition = position; 
    this.mContext = context; 
    this.mPager = viewPager; 

} 

@Override 
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) { 

    View view = null; 

    try { 
     switch (mPosition) { 

      case 0: 
       view = inflater.inflate(R.layout.fragment_welcome1, container, false); 

       Typeface robotoLight = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Roboto-Light.ttf"); 
       TextView welcomeTxt1x2 = (TextView) view.findViewById(R.id.welcome_text_1_2); 

       Button startButton = (Button) view.findViewById(R.id.welcome_btn_1_1); 


       startButton.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View view) { 
         mPager.setCurrentItem(1); 
        } 
       }); 
       welcomeTxt1x2.setTypeface(robotoLight); 
     } 
    } catch (NullPointerException e) { 
     e.printStackTrace(); 
    } 

    return view; 
} 

} 

Et voici ma FragmentActivity classe avec la classe FragmentStatePagerAdapter en son sein -

package com.cosine.arc; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentStatePagerAdapter; 
import android.support.v4.view.PagerAdapter; 

public class IntroActivity extends FragmentActivity { 

private static int NUM_PAGES = 3; 

private NonSwipeableViewPager mPager; 
private PagerAdapter mPagerAdapter; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_intro); 

    mPager = (NonSwipeableViewPager) findViewById(R.id.intro_pager); 
    mPagerAdapter = new IntroSliderAdapter(getSupportFragmentManager()); 
    mPager.setAdapter(mPagerAdapter); 

} 

@Override 
public void onBackPressed() { 
    if (mPager.getCurrentItem()==0) { 
     super.onBackPressed(); 
    } 
    else { 
     mPager.setCurrentItem(mPager.getCurrentItem()-1); 
    } 
} 

public int getCurrentItem() { 
    return mPager.getCurrentItem(); 
} 

public NonSwipeableViewPager getPagerUpdate() { 

    return mPager; 
} 

private class IntroSliderAdapter extends FragmentStatePagerAdapter { 

    public IntroSliderAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return new WelcomeFragment(getBaseContext(), mPager, position); 
    } 

    @Override 
    public int getCount() { 
     return NUM_PAGES; 
    } 

} 
} 

Et voici le journal des erreurs -

04-07 15:25:13.774 12186-12186/com.cosine.arc E/AndroidRuntime: FATAL EXCEPTION: main 
    Process: com.cosine.arc, PID: 12186 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.view.ViewPager.setCurrentItem(int)' on a null object reference 
    at com.cosine.arc.WelcomeFragment$1.onClick(WelcomeFragment.java:58) 
    at android.view.View.performClick(View.java:5612) 
    at android.view.View$PerformClick.run(View.java:22288) 
    at android.os.Handler.handleCallback(Handler.java:751) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:154) 
    at android.app.ActivityThread.main(ActivityThread.java:6123) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757) 

fragment_welcome1.xml -

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.cosine.arc.WelcomeFragment"> 

<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@color/colorPrimary"> 

    <TextView 
     android:id="@+id/welcome_text_1_1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:text="@string/welcome_to_" 
     android:textColor="@android:color/white" 
     android:textSize="36sp" 
     android:padding="16dp" 
     android:layout_marginTop="16dp" 
     android:gravity="center"/> 

    <ImageView 
     android:id="@+id/welcome_img_1_1" 
     android:layout_width="150dp" 
     android:layout_height="150dp" 
     android:src="@drawable/ic_logo" 
     android:layout_below="@id/welcome_text_1_1" 
     android:layout_centerHorizontal="true"/> 

    <TextView 
     android:id="@+id/welcome_text_1_2" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@id/welcome_img_1_1" 
     android:text="@string/lets_get_things_started_" 
     android:textSize="42sp" 
     android:textColor="@android:color/white" 
     android:padding="16dp" 
     android:layout_marginTop="32dp"/> 

    <Button 
     android:id="@+id/welcome_btn_1_1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:background="@android:color/white" 
     android:text="Start" 
     android:textColor="@android:color/black" 
     android:layout_margin="16dp" 
     android:layout_alignParentRight="true" 
     android:drawableRight="@mipmap/ic_arrow_right_light"/> 

</RelativeLayout> 

S'il vous plaît noter que je n'ai deux fichiers de mise en page différentes fragment_welcome1.xml et fragment_welcome1.xml-land.

Répondre

0

Lors de la modification de l'orientation, vous devrez enregistrer l'instance du fragment si vous souhaitez conserver les références. Jetez un oeil à ce answer, espérons que cela vous aide. En un mot, je pense que vous devrez sauvegarder l'instance du fragment dans onSaveInstanceState() de votre conteneur, puis recréer votre fragment enregistré lorsque l'orientation change.

Veuillez noter que effectuer des modifications de configuration dans le manifeste n'est pas la méthode recommandée pour enregistrer l'instance du fragment. Faire des changements de configuration conduira à des fuites de mémoire.

+0

Cette méthode fonctionne bien lorsque la classe 'Fragment' est utilisée dans le fichier de ressources de mise en page. Mais j'ai suivi la documentation officielle d'Android pour [Utilisation de ViewPager for Screen Slides] (https://developer.android.com/training/animation/screen-slide.html) et il n'a pas utilisé la classe 'Fragment' à cette fin et donc je l'ai évité dans mon projet aussi bien. J'ai ajouté mon fichier de ressources de mise en page à la question, veuillez vérifier. – Swap

+0

Cela fonctionnera lorsque vous ajouterez dynamiquement de nouveaux fragments à votre activité de conteneur. Vous pouvez enregistrer l'état des fragments lors de la rotation du périphérique et vous pouvez également enregistrer les valeurs définies dans vos classes POJO. Jetez un oeil à [ce lien] (http://stackoverflow.com/questions/7951730/viewpager-and-fragments-whats-the-right-way-to-store-fragments-state) –