0

ViewPagerをAndroidアプリにワンタイム設定画面として追加しようとしています。しかし、私が直面している問題は、画面の向きが変更されたときにアプリがクラッシュするということです。の中にセットアッププロセスがあります。Android ViewPagerは方向変更時にNullPointerExceptionをクラッシュさせます

アプリをポートレートモードまたはランドスケープモードで開いて、向きを変更せずに使用すると、正常に動作します。しかし、実行時に方向が変更された場合は、のsetCurrentItem(int position)メソッドを使用するとアプリケーションがクラッシュします。

は、ここに私のFragmentクラスだ -

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

} 

そしてここで、その中にFragmentStatePagerAdapterクラスと私のFragmentActivityクラスだ -

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

} 
} 

をそしてここでエラーログです -

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> 

私は2つの異なるレイアウトファイルfragment_welcome1.xmlfragment_welcome1.xml-landを持っていることに注意してください。

答えて

0

方向を変更した場合、参照を保持する場合は、フラグメントのインスタンスを保存する必要があります。これを見てくださいanswer、それがあなたを助けてくれることを願っています。簡単に言えば、私はあなたのコンテナアクティビティのonSaveInstanceState()のフラグメントのインスタンスを保存し、向きが変わったときに保存されたフラグメントを再作成する必要があると思います。

マニフェストの設定を変更するは、フラグメントのインスタンスを保存するために推奨される方法ではありません()。設定を変更するとメモリリークが発生します。

+0

このメソッドは、レイアウトリソースファイルで 'Fragment'クラスを使用するとうまく動作します。しかし、私は[Screen SlidesのためのViewPagerの使用](https://developer.android.com/training/animation/screen-slide.html)の公式のAndroidドキュメントに従っており、目的のために 'Fragment'クラスを使用していませんでした。私のプロジェクトでもそれを避けました。レイアウトリソースファイルを質問に追加しました。確認してください。 – Swap

+0

新しいフラグメントをコンテナアクティビティに動的に追加すると機能します。デバイスが回転しているときにフラグメントの状態を保存したり、POJOクラスに設定されている値を保存することもできます。 [this link](http://stackoverflow.com/questions/7951730/viewpager-and-fragments-whats-the-right-way-to-store-fragments-state)を見てください。 –

関連する問題