我有一个带ViewPager的简单片段。
我正在使用最新的支持库,v4 rev18!
如果我第一次显示它,一切正常,如果我回去再显示一下,应用程序会崩溃并出现以下异常:
java.lang.NullPointerException
at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:569)
at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:211)
at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1281)
at android.view.View.dispatchRestoreInstanceState(View.java:12043)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2688)
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2694)
at android.view.View.restoreHierarchyState(View.java:12021)
at android.support.v4.app.Fragment.restoreViewState(Fragment.java:425)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:949)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4800)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:798)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:565)
at dalvik.system.NativeStart.main(Native Method)
我的简单课程看起来像下面一样,实际上应该很好......
public class RoutineDayFragment extends BaseFragment
{
private RoutinesActivity mParent = null;
@InjectView(R.id.pager)
MyViewPager pager = null;
@InjectView(R.id.indicator)
PagerSlidingTabStrip indicator = null;
private FragmentStatePagerAdapter mAdapter = null;
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
mParent = ((RoutinesActivity) getBaseActivity());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.view_pager, container, false);
Views.inject(this, v);
mAdapter = new FragmentStatePagerAdapter(getChildFragmentManager())
{
@Override
public int getCount()
{
if (mParent.getSharedData().selectedRoutine == -1)
return 0;
return mParent.getSharedData().routines.get(mParent.getSharedData().selectedRoutine).getRWorkoutDay().size();
}
@Override
public Fragment getItem(int pos)
{
return DayFragment.newInstance(pos);
}
@Override
public CharSequence getPageTitle(int pos)
{
return Common.getString(R.string.day) + (pos + 1);
}
};
pager.setAdapter(mAdapter);
indicator.setViewPager(pager);
return v;
}
}
答案 0 :(得分:15)
使用 AsyncTask 设置ViewPagerAdapter:
private class SetAdapterTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onPostExecute(Void result) {
if(mAdapter != null) mViewPager.setAdapter(mAdapter);
}
}
这样称呼:
mAdapter = new PageAdapter(getChildFragmentManager());
new SetAdapterTask().execute();
并且重置片段的onResume(
)方法中的适配器。
我创造了什么?
这是 Main Activity.java
它包含两个适配器,一个用于主片段,一个用于子片段。此外,它们是两个Fragment类,一个是包含ViewPager的Fragment(主片段),另一个是子片段(嵌套的ViewPager内部)
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
NonSwipeableViewPager mViewPager;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Set up the ViewPager, attaching the adapter and setting up a listener for when the
// user swipes between sections.
mViewPager = (NonSwipeableViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setText(mAppSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {}
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {}
public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
switch (i) {
default:
// The other sections of the app are dummy placeholders.
Fragment fragment = new ViewPagerContainerFragment();
return fragment;
}
}
@Override
public int getCount() {
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
return "Tab " + (position +1);
}
}
public static class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
switch (i) {
default:
// The other sections of the app are dummy placeholders.
Fragment fragment = new ViewPagerFragment();
Bundle b = new Bundle();
b.putString("key", "I am fragment nr " + i);
fragment.setArguments(b);
return fragment;
}
}
@Override
public int getCount() {
return 10;
}
}
/**
* THIS FRAGMENT CONTAINS A VIEWPAGER
*/
public static class ViewPagerContainerFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.main_fragment, container, false);
ViewPager pager = (ViewPager) rootView.findViewById(R.id.nestedViewPager);
pager.setAdapter(new ViewPagerAdapter(getChildFragmentManager()));
return rootView;
}
}
/**
* THIS FRAGMENT IS INSIDE THE VIEWPAGER
*/
public static class ViewPagerFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.sub_fragment, container, false);
((TextView) rootView.findViewById(R.id.tv1)).setText(getArguments().getString("key"));
((TextView) rootView.findViewById(R.id.tv1)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), CollectionDemoActivity.class);
startActivity(intent);
}
});
return rootView;
}
}
}
<强> activity_main.xml中强>
<com.example.android.effectivenavigation.NonSwipeableViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<强> main_fragment.xml 强>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/nestedViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="24sp" />
<强> sub_fragment.xml 强>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="50sp" />
最终结果如下:
我们有3个顶级片段,每个片段包含一个包含10个片段的ViewPager。