0

사용자의 일회성 설정 화면으로 Android 앱에 ViewPager을 추가하려고합니다. 그러나 내가 직면 한 문제는 화면의 방향이 바뀌면 앱이 계속 충돌한다는 것입니다. 가운데 설정 프로세스가 진행됩니다.오리엔테이션 변경시 NullPointerException이 발생하여 Android ViewPager가 계속 충돌합니다.

앱이 세로 또는 가로 모드로 열리고 방향 변경없이 사용되는 경우 제대로 작동합니다. 그러나 실행 중에 오리엔테이션이 변경되면 에있는 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> 

나는 두 개의 서로 다른 레이아웃 파일 fragment_welcome1.xmlfragment_welcome1.xml-land이 적어주세요.

답변

0

방향 변경시 참조를 유지하려면 조각의 인스턴스를 저장해야합니다. 이 answer을 보시고 도움을 받으시길 바랍니다. 간단히 말해, 컨테이너 작업의 onSaveInstanceState()에서 단편의 인스턴스를 저장 한 다음 방향이 바뀌면 저장된 단편을 다시 작성해야한다고 생각합니다.

매니페스트에서 구성 변경을 수행하는 은 조각의 인스턴스를 저장하는 데 권장되는 방법이 아닙니다 (). 구성을 변경하면 메모리 누수가 발생합니다.

+0

이 방법은 'Fragment' 클래스가 레이아웃 리소스 파일에서 사용될 때 잘 작동합니다. 그러나 [스크린 슬라이드 용 ViewPager 사용하기] (https://developer.android.com/training/animation/screen-slide.html)에 대한 공식 안드로이드 문서를 따랐으며 목적을 위해'Fragment' 클래스를 사용하지 않았습니다. 그래서 나는 내 프로젝트에서도 그것을 피했다. 내 레이아웃 리소스 파일을 질문에 추가했습니다. 확인하십시오. – Swap

+0

컨테이너 활동에 새 조각을 동적으로 추가 할 때 작동합니다. 장치 회전시 조각의 상태를 저장할 수 있으며 POJO 클래스에 설정된 값을 저장할 수도 있습니다. [this link] (http://stackoverflow.com/questions/7951730/viewpager-and-fragments-whats-the-right-way-to-store-fragments-state)를보십시오. –

관련 문제