0

我试图将ViewPager添加到我的Android应用程序,作为用户的一次性设置屏幕。但是我面临的问题是,当屏幕的方向改变在设置过程中时,应用程序不断崩溃。Android ViewPager在定位更改时不断崩溃NullPointerException

如果应用程序以纵向或横向模式打开并且在没有任何方向更改的情况下使用,则它可以正常工作。但是如果在运行期间更改方向,则使用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; 
} 

} 

这是我的FragmentActivity类与FragmentStatePagerAdapter类中它 -

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'类时,此方法运行良好。但是我遵循官方Android文档[使用ViewPager作为屏幕幻灯片](https://developer.android.com/training/animation/screen-slide.html),并没有使用“Fragment”类来达到目的,因此我在我的项目中也避开了它。我已将我的布局资源文件添加到问题中,请检查。 – Swap

+0

当您动态地将新片段添加到您的容器活动时,它将起作用。您可以在设备旋转时保存片段的状态,并且还可以保存在POJO类中设置的值。看看[这个链接](http://stackoverflow.com/questions/7951730/viewpager-and-fragments-whats-the-right-way-to-store-fragments-state) –