我正在尝试将ViewPager
添加到我的Android应用中作为用户的一次性设置屏幕。但我面临的问题是,当在设置过程中更改屏幕的方向时,应用程序会一直崩溃。
如果应用程序以纵向或横向模式打开并且在没有任何方向更改的情况下使用,则可以正常工作。但是如果在运行时期间更改了方向,则使用setCurrentItem(int position)
上的方法ViewPager
会使应用程序崩溃。
这是我的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.xml
和fragment_welcome1.xml-land
。
答案 0 :(得分:0)
在方向更改时,如果要保留引用,则必须保存片段的实例。看看这个answer,希望它可以帮到你。简而言之,我认为您需要在容器活动的onSaveInstanceState()中保存片段的实例,然后在方向更改时重新创建已保存的片段。
请注意在清单中进行配置更改不是建议的方式来保存片段的实例。进行配置更改将导致内存泄漏。