FragmentPagerAdapter getItem未被触发

时间:2022-07-31 23:58:15

Currently, with a FragmentActivity, I toggle among 2 type of Fragments using the following code.

目前,使用FragmentActivity,我使用以下代码在2种类型的片段之间切换。

private void toggle() {
    Fragment oldFragment = getSupportFragmentManager().findFragmentById(R.id.content);
    Fragment fragment = null;
    if (oldFragment instanceof ColorFragment) {
        fragment = new ViewPagerFragment();
    } else {
        fragment = new ColorFragment(android.R.color.black);
    }

    getSupportFragmentManager().beginTransaction().replace(R.id.content, fragment).commitAllowingStateLoss();
}

2 Fragments are being toggle.

2片段正在切换。

  • ColorFragment - A simple fragment which fill up its background with solid black color.
  • ColorFragment - 一个简单的片段,用纯黑色填充背景。
  • ViewPagerFragment - A fragment contains ViewPager. User can swipe between a purple color fragment, and a blue color fragment.
  • ViewPagerFragment - 一个包含ViewPager的片段。用户可以在紫色片段和蓝色片段之间滑动。

The code which responsible for swiping purple and blue color fragments are as below.

负责刷紫色和蓝色碎片的代码如下。

private static class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    public MyFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return 2;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
        case 0:
            return new ColorFragment(android.R.color.holo_purple);
        default:
            return new ColorFragment(android.R.color.holo_blue_bright);
        }
    }      
} 

However, I encounter the weird behavior during toggling.

但是,我在切换期间遇到了奇怪的行为。

  1. Black color fragment was shown.
  2. 显示黑色片段。
  3. Toggling.
  4. 切换。
  5. View pager, which can swipe between purple and blue fragments shown.
  6. 查看寻呼机,可以在显示的紫色和蓝色片段之间滑动。
  7. Toggling.
  8. 切换。
  9. Black color fragment was shown.
  10. 显示黑色片段。
  11. Toggling.
  12. 切换。
  13. Nothing shown, as MyFragmentPagerAdapter's getItem is not being triggered.
  14. 没有显示,因为没有触发MyFragmentPagerAdapter的getItem。

I think my situation is similar to FragmentPagerAdapter getItem is not called

我认为我的情况类似于FragmentPagerAdapter没有调用getItem

However, I prefer not to use FragmentStatePagerAdapter, because of the cost of potentially more overhead when switching between pages.

但是,我不想使用FragmentStatePagerAdapter,因为在页面之间切换时可能会产生更多开销。

Any workaround to overcome this problem?

解决这个问题的任何解决方法?

I include a complete workable source code to demonstrate this problem : https://www.dropbox.com/s/jok9tz5ktvfcteo/viewpagerbug.zip

我提供了一个完整可行的源代码来演示此问题:https://www.dropbox.com/s/jok9tz5ktvfcteo/viewpagerbug.zip

5 个解决方案

#1


104  

Any workaround to overcome this problem?

解决这个问题的任何解决方法?

I've downloaded your code and the problem appears because you don't handle those Fragments right. Most precisely you use nested Fragments in the ViewPager based Fragment and for that ViewPager you create the adapter like this:

我已经下载了您的代码并且出现了问题,因为您没有正确处理这些碎片。最精确的是,您在基于ViewPager的Fragment中使用嵌套的Fragments,对于ViewPager,您可以像这样创建适配器:

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getFragmentManager());

Instead, you should be using getChildFragmentManager() to bind the nested fragments:

相反,您应该使用getChildFragmentManager()来绑定嵌套的片段:

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getChildFragmentManager());

Also, you shouldn't pass data through a constructor to a Fragment as that data will not survive a configuration change and bad things will start to appear. Use a Bundle instead.

此外,您不应该通过构造函数将数据传递给Fragment,因为数据将无法在配置更改后继续存在,并且会出现不良内容。请改用Bundle。

#2


12  

Global working tested solution.

全球工作测试解决方案

getSupportFragmentManager() keeps the null reference some times and View pager does not create new fragment instance.Since it finds reference to same fragment. So to over come this use getChildFragmentManager() solves problem in simple way.

getSupportFragmentManager()多次保留空引用,而View寻呼机不会创建新的片段实例。因为它找到对同一片段的引用。因此,使用getChildFragmentManager()以简单的方式解决问题。

Don't

new PagerAdapter(getSupportFragmentManager(), fragments);

新的PagerAdapter(getSupportFragmentManager(),片段);

Do

new PagerAdapter(getChildFragmentManager() , fragments);

新的PagerAdapter(getChildFragmentManager(),片段);

#3


0  

In my case I was correctly calling

在我的情况下,我正确地打电话

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getChildFragmentManager());

but then in the nested fragment I was trying to replace the container fragment with another one by using:

但是在嵌套片段中,我试图通过使用以下方法将容器片段替换为另一个容器片段:

getFragmentManager()

You need to go to the activity and call

你需要去活动并打电话

getActivity().getSupportFragmentManager();

#4


0  

In my cases it worked after add this to my FragmentPagerAdapter:

在我的情况下,它添加到我的FragmentPagerAdapter后工作:

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

and I also used getChildFragmentManager() like Luksprog said

我也像Luksprog所说的那样使用了getChildFragmentManager()

#5


0  

Simple use FragmentStatePagerAdapter instead of FragmentPagerAdapter

简单地使用FragmentStatePagerAdapter而不是FragmentPagerAdapter

or

要么

you can use new MyFragmentPagerAdapter(this.getChildFragmentManager())

你可以使用新的MyFragmentPagerAdapter(this.getChildFragmentManager())

Hope it will help you :)

希望它能帮到你:)

#1


104  

Any workaround to overcome this problem?

解决这个问题的任何解决方法?

I've downloaded your code and the problem appears because you don't handle those Fragments right. Most precisely you use nested Fragments in the ViewPager based Fragment and for that ViewPager you create the adapter like this:

我已经下载了您的代码并且出现了问题,因为您没有正确处理这些碎片。最精确的是,您在基于ViewPager的Fragment中使用嵌套的Fragments,对于ViewPager,您可以像这样创建适配器:

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getFragmentManager());

Instead, you should be using getChildFragmentManager() to bind the nested fragments:

相反,您应该使用getChildFragmentManager()来绑定嵌套的片段:

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getChildFragmentManager());

Also, you shouldn't pass data through a constructor to a Fragment as that data will not survive a configuration change and bad things will start to appear. Use a Bundle instead.

此外,您不应该通过构造函数将数据传递给Fragment,因为数据将无法在配置更改后继续存在,并且会出现不良内容。请改用Bundle。

#2


12  

Global working tested solution.

全球工作测试解决方案

getSupportFragmentManager() keeps the null reference some times and View pager does not create new fragment instance.Since it finds reference to same fragment. So to over come this use getChildFragmentManager() solves problem in simple way.

getSupportFragmentManager()多次保留空引用,而View寻呼机不会创建新的片段实例。因为它找到对同一片段的引用。因此,使用getChildFragmentManager()以简单的方式解决问题。

Don't

new PagerAdapter(getSupportFragmentManager(), fragments);

新的PagerAdapter(getSupportFragmentManager(),片段);

Do

new PagerAdapter(getChildFragmentManager() , fragments);

新的PagerAdapter(getChildFragmentManager(),片段);

#3


0  

In my case I was correctly calling

在我的情况下,我正确地打电话

MyFragmentPagerAdapter myFragmentPagerAdapter = new MyFragmentPagerAdapter(this.getChildFragmentManager());

but then in the nested fragment I was trying to replace the container fragment with another one by using:

但是在嵌套片段中,我试图通过使用以下方法将容器片段替换为另一个容器片段:

getFragmentManager()

You need to go to the activity and call

你需要去活动并打电话

getActivity().getSupportFragmentManager();

#4


0  

In my cases it worked after add this to my FragmentPagerAdapter:

在我的情况下,它添加到我的FragmentPagerAdapter后工作:

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

and I also used getChildFragmentManager() like Luksprog said

我也像Luksprog所说的那样使用了getChildFragmentManager()

#5


0  

Simple use FragmentStatePagerAdapter instead of FragmentPagerAdapter

简单地使用FragmentStatePagerAdapter而不是FragmentPagerAdapter

or

要么

you can use new MyFragmentPagerAdapter(this.getChildFragmentManager())

你可以使用新的MyFragmentPagerAdapter(this.getChildFragmentManager())

Hope it will help you :)

希望它能帮到你:)