使用 FragmentPagerAdapter 的 ViewPager 中的片段在第二次查看时是空白的

我有一个片段界面,沿着底部的选项卡,在主视图中打开不同的片段。

我有一个特别的片段,是一个项目列表。如果用户选择了这个列表中的一个项目,那么将打开另一个片段,其中包含一个视图页面,在前一个片段中的列表中的所有项目之间水平滚动。效果很好。

视图页面使用了一个 FragmentPagerAdapter 来显示项目。

当用户在列表中选择一个项目,查看它,然后点击标签栏上的按钮返回到列表,然后选择另一个项目时,问题就出现了。第二次选中某个项时,将出现一个空白屏幕,而不是视图页。发生这种情况时,我的 LogCat 中没有收到错误。

为什么浏览器只是第一次出现?

FragmentPagerAdapter:

public class ViewPagerAdapter extends FragmentPagerAdapter {
Cursor mCursor;


public ViewPagerAdapter(FragmentManager fm, Cursor c) {
super(fm);
mCursor = c;
}


public void changeCursor(Cursor c) {
mCursor = c;
this.notifyDataSetChanged();
}


@Override
public int getCount() {
if (mCursor == null) return 0;
else return mCursor.getCount();
}


@Override
public Fragment getItem(int position) {
mCursor.moveToPosition(position);
return TeamCardFragment.newInstance(mCursor, position);
}
}

PagerFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = getArguments();
mCursorPosition = bundle.getInt(TeamCardCommon.BUNDLE_KEY_CURSOR_POSITION);


View mView = inflater.inflate(R.layout.team_card_master, container, false);
mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);


mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
new setAdapterTask().execute();


return mView;
}


private class setAdapterTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
return null;
}


@Override
protected void onPostExecute(Void result) {
mViewPager.setAdapter(mAdapter);
mViewPager.setCurrentItem(mCursorPosition);
}
}
38751 次浏览

We got around this by re-implementing the view pager items as standard views rather than fragments and changing the adapter accordingly.

I had the same issue. Changing the parent class of my PageAdapter from android.support.v4.app.FragmentPagerAdapter to android.support.v4.app.FragmentStatePagerAdapter solve my ViewPager display issue on "second time"!

I managed to solve this by replacing getFragmentManager() with getChildFragmentManager() in the parent fragment. This parent fragment was instancing an android.support.v4.app.FragmentPagerAdapter in order to contain pageable (slideable) fragments, which requires a fragment manager in the constructor. To this constructor I passed the return value of getChildFragmentManager().

hackbod's link was key (https://developer.android.com/about/versions/android-4.2.html#NestedFragments), which was found in this post Fragments within Fragments

To nest a fragment, simply call getChildFragmentManager() on the Fragment in which you want to add a fragment. This returns a FragmentManager that you can use like you normally do from the top-level activity to create fragment transactions.

In my very particular case, where I was using a CoordinatorLayout with an AppBarLayout and the ViewPager, what solved it for me was removing the android:fitsSystemWindows="true" from my AppBarLayout xml properties.

Don't ask me why. I know it sounds a little bit ridiculous and like it should have no correlation, but it was this single line the only thing that was causing trouble as I was already using getChildFragmentManager() in my adapter. I spent a whole day debugging my code just to find this, so I hope it saves someone else some time.

You can also initialize the adapter for cases where you experience this error when your app is minimized and later called up.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = getArguments();
mCursorPosition = bundle.getInt(TeamCardCommon.BUNDLE_KEY_CURSOR_POSITION);
View mView = inflater.inflate(R.layout.team_card_master, container, false);
mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);
initViewPagerAdapter();
return mView;
}
private void initViewPagerAdapter(){
mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
new setAdapterTask().execute();
}


@Override
public void onResume(){
super.onResume();
initViewPagerAdapter();
}

for me i had to call this on my viewpager:

myViewPager.setSaveFromParentEnabled(false);

I had the issue where the viewpager was not refreshing and all i saw was a blank white screen where the fragments should be. I was passing in getChildFragmentManager but it did not help.

I had the same thing, in the second time i call the Pager Adapter, the child view return a NullPointerException. And changing the adapder in FragmentStatePagerAdapter solve my issue too.

I had the same issue for which I changed adapter from FragmentPagerAdapter to FragmentStatePagerAdapter and getFragmentManager() in the parent fragment to getChildFragmentManager()

The reason behind this is FragmentStatePagerAdapter is helpful in storing a large number of pages and memory associated with each page visited is less as it keeps only the saved state of the fragment while the page is not visible. This reduces the overhead while switching between the fragments.

I was getting this same problem on Xamarin Android with a blank screen the second time around.. Setting the following fixed it for me.

viewPager.SaveFromParentEnabled = false;

This would help you.

    viewPager.setOffscreenPageLimit(position);

Try to put setOffscreenPageLimit (int limit) on parent ViewPager.

mViewPager.setOffscreenPageLimit(totalPages-1);

This worked for me like charm.

In my case I had fragment inside TabLayout with ViewPager.

And another ViewPager inside that fragment. First time all working fine but when I change tab and return back, some of my fragment gone blank.

Change FragmentPagerAdapter into FragmentStatePagerAdapter Use getChildFragmentManager() instead of getFragmentManager()

getChildFragmentManager() - because according to documentation, it will return a private FragmentManager for placing and managing Fragments inside of this Fragment. Meanwhile getFragmentManager() will return the FragmentManager for interacting with fragments associated with this activity

class ViewPagerAdapter extends FragmentStatePagerAdapter this work for me try this

simply call getChildFragmentManager() in adapter .Then you will not get blank in multiple click

I had a similar issue using ViewPager2 and FragmentStateAdapter. When replacing the Fragment (containing a viewpager2 and tabs of fragments) I realized the onDestroyView() method was being called after the new fragment was set up. I fixed this by calling FragmentTransaction.popBackStack() before replacing the fragment, which seemed to clean up the old fragment before creating the new one.

This issue started for me after updating androidx.appcompat:appcompat beyond version 1.2. My Fragment also used to use setRetainInstance(false) which is now deprecated, I'm unsure if that was part of the issue.