102

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

我有一个特定的片段,它是一个项目列表。如果用户选择此列表中的一个项目,则会打开另一个片段,其中包含一个视图分页器,该页面在前一个片段的列表中的所有项目之间水平滚动。这很好用。

viewpager 使用 FragmentPagerAdapter 来显示项目。

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

为什么 viewpager 只在第一次出现?

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);
    }
}
4

14 回答 14

223

我遇到过同样的问题。更改我的 PageAdapter 的父类,android.support.v4.app.FragmentPagerAdapterandroid.support.v4.app.FragmentStatePagerAdapter解决我ViewPager“第二次”的显示问题!

于 2011-12-12T17:01:12.930 回答
89

我设法通过替换父片段中的getFragmentManager()with来解决这个问题。getChildFragmentManager()这个父片段实例化了一个android.support.v4.app.FragmentPagerAdapter以包含可分页(可滑动)片段,这需要构造函数中的片段管理器。我将返回值传递给这个构造函数getChildFragmentManager()

hackbod 的链接是关键(https://developer.android.com/about/versions/android-4.2.html#NestedFragments),可以在这篇文章Fragments inside Fragments 中找到

要嵌套片段,只需调用getChildFragmentManager()要在其中添加片段的片段即可。这将返回一个 FragmentManager,您可以像通常从顶级活动中一样使用它来创建片段事务。

于 2014-03-27T03:16:39.857 回答
18

对我来说,我不得不在我的查看器上调用它:

myViewPager.setSaveFromParentEnabled(false);

我遇到了viewpager没有刷新的问题,我看到的只是一个空白的白色屏幕,片段应该在哪里。我正在传递 getChildFragmentManager 但它没有帮助。

于 2017-07-12T04:11:30.720 回答
11

在我非常特殊的情况下,我将 CoordinatorLayout 与 AppBarLayout 和 ViewPager 一起使用,为我解决的问题是从我的 AppBarLayout xml 属性中删除 android:fitsSystemWindows="true"

不要问我为什么。我知道这听起来有点荒谬,并且应该没有相关性,但这是唯一造成麻烦的单行,因为我已经在我的适配器中使用了 getChildFragmentManager()。我花了一整天的时间调试我的代码只是为了找到这个,所以我希望它可以节省其他人一些时间。

于 2016-07-22T00:36:46.383 回答
10

我遇到了同样的问题,我将适配器从FragmentPagerAdapter父片段更改为FragmentStatePagerAdaptergetFragmentManager()getChildFragmentManager()

这背后的原因FragmentStatePagerAdapter是有助于存储大量页面,并且与访问的每个页面相关联的内存更少,因为它仅保留片段的已保存状态,而页面不可见。这减少了在片段之间切换时的开销。

于 2017-08-16T16:33:55.643 回答
4

尝试穿上父 ViewPagersetOffscreenPageLimit (int limit)

mViewPager.setOffscreenPageLimit(totalPages-1);

这对我来说就像魅力一样。

就我而言,我里面有TabLayout碎片ViewPager.

还有ViewPager那个片段里面的另一个。第一次一切正常,但是当我更改选项卡并返回时,我的一些片段变为空白。

于 2018-10-04T07:00:00.030 回答
2

这会对你有所帮助。

    viewPager.setOffscreenPageLimit(position);
于 2018-08-21T07:27:27.397 回答
1

我们通过将视图分页器项重新实现为标准视图而不是片段并相应地更改适配器来解决这个问题。

于 2011-11-29T19:24:38.700 回答
1

类 ViewPagerAdapter 扩展 FragmentStatePagerAdapter 这个工作对我来说试试这个

于 2020-05-06T05:34:14.803 回答
1

我第二次在Xamarin Android上遇到了同样的问题,但出现了空白屏幕。设置以下内容为我解决了这个问题。

viewPager.SaveFromParentEnabled = false;
于 2017-09-03T07:03:37.947 回答
1

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

于 2020-12-03T09:02:09.920 回答
0

当您的应用程序被最小化并在以后调用时遇到此错误,您还可以初始化适配器。

@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();
}
于 2016-07-24T16:38:16.243 回答
0

改为 使用FragmentPagerAdapter而不是FragmentStatePagerAdaptergetChildFragmentManager()getFragmentManager()

getChildFragmentManager()- 因为根据文档,它将返回一个私有 FragmentManager 用于在该 Fragment 内放置和管理 Fragment。同时getFragmentManager()将返回 FragmentManager 用于与与此活动关联的 Fragment 进行交互

于 2018-10-23T12:02:46.667 回答
0

我有同样的事情,在我第二次调用寻呼适配器时,子视图返回 NullPointerException。并且更改 FragmentStatePagerAdapter 中的适配器也解决了我的问题。

于 2017-08-04T02:00:28.017 回答