Android FragmentPagerAdapter getItem 未被调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12581896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:05:54  来源:igfitidea点击:

FragmentPagerAdapter getItem is not called

androidandroid-fragmentsandroid-fragmentactivity

提问by Kanika

I am not able to reuse fragment in FragmentPagerAdapter.. Using destroyItem() method, It is deleting the fragment but still does not called getItem() again..There are just 2-3 Images so I am using FragmentPagerAdapter Instead of FragmentStatePagerAdapter..

我无法在 FragmentPagerAdapter 中重用片段。

public class ExamplePagerAdapter extends FragmentPagerAdapter {

    ArrayList < String > urls;
    int size = 0;
    public ExamplePagerAdapter(FragmentManager fm, ArrayList < String > res) {
        super(fm);
        urls = res;
        size = urls.size();
    }

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

    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }

    @Override
    public Fragment getItem(int position) {

        Fragment fragment = new FloorPlanFragment();
        Bundle b = new Bundle();
        b.putInt("p", position);
        b.putString("image", urls.get(position));
        Log.i("image", "" + urls.get(position));
        fragment.setArguments(b);
        return fragment;
    }
}

And In FragmentActivity,

在 FragmentActivity 中,

pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2)); 

回答by Kanika

KISS Answer:

吻 答案:

Simple use FragmentStatePagerAdapterinstead of FragmentPagerAdapter.

简单地使用FragmentStatePagerAdapter而不是FragmentPagerAdapter

I got the answer.. Firstly I thought to delete this question as I am doing a very silly mistake but this answer will help someone who is facing the same problem that Instead of FragmentPagerAdapter, use FragmentStatePagerAdapter.

我得到了答案.. 首先,我想删除这个问题,因为我犯了一个非常愚蠢的错误,但这个答案将帮助面临同样问题的人,而不是FragmentPagerAdapter使用FragmentStatePagerAdapter.

As @BlackHatSamurai mentioned in the comment:

正如@BlackHatSamurai 在评论中提到的:

The reason this works is because FragmentStatePagerAdapterdestroys as Fragments that aren't being used. FragmentPagerAdapterdoes not.

这样做的原因是因为FragmentStatePagerAdapter销毁为未使用的 Fragment。FragmentPagerAdapter才不是。

回答by Jraco11

Using a FragmentStatePagerAdapterdidn't fully fix my problem which was a similar issue where onCreateViewwas not being called for child fragments in the view pager. I am actually nesting my FragmentPagerAdapterinside of another Fragmenttherefore the FragmentManagerwas shared throughout all of them and thus retaining instances of the old fragments. The fix was to instead feed an instance of the getChildFragmentManagerto the constructor of the FragmentPagerAdapterin my host fragment. Something like...

使用 aFragmentStatePagerAdapter并没有完全解决我的问题,这是一个类似的问题,onCreateView在视图寻呼机中没有被调用子片段。我实际上是将我的FragmentPagerAdapter内部嵌套在另一个内部,Fragment因此FragmentManager所有这些都共享,从而保留了旧片段的实例。解决方法是将 的实例提供getChildFragmentManagerFragmentPagerAdapter主机片段中的的构造函数。就像是...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());

The getChildFragmentManager()method is accessible via a fragment and this worked for me because it returns a private FragmentManagerfor that fragment specifically for situations in which nesting fragments is needed. I hope this helps someone who may be having the same problem I was!!

getChildFragmentManager()方法可通过片段访问,这对我有用,因为它FragmentManager专门为需要嵌套片段的情况返回该片段的私有。我希望这可以帮助那些可能与我遇到同样问题的人!!

  • Keep in mind however to use getChildFragmentManager()your minimum API version must be atleast 17 (4.2), so this may throw a wrench in your gears. Of course, if you are using fragments from the support library v4 you should be okay.
  • 但是请记住,要使用getChildFragmentManager()您的最低 API 版本必须至少为17 (4.2),因此这可能会给您带来麻烦。当然,如果您使用支持库 v4 中的片段,您应该没问题。

回答by vedant

Override long getItemId (int position)

覆盖 long getItemId (int position)

FragmentPagerAdaptercaches the fragments it creates using getItem. I was facing the same issue- even after calling notifyDataSetChanged()getItemwas not being called.

FragmentPagerAdapter缓存它使用getItem. 我面临着同样的问题 - 即使在notifyDataSetChanged()getItem没有被调用之后。

This is actually a feature and not a bug. You need to override getItemIdso that you can correctly reuse your fragments. Since you are removing fragments, your positions are changing. As mentioned in the docs:

这实际上是一个功能,而不是一个错误。您需要覆盖,getItemId以便您可以正确地重用您的片段。由于您正在移除碎片,因此您的位置正在发生变化。如文档中所述:

long getItemId (int position)

Return a unique identifier for the item at the given position.

The default implementation returns the given position. Subclasses should override this method if the positions of items can change.

long getItemId (int position)

返回给定位置的项目的唯一标识符。

默认实现返回给定的位置。如果项目的位置可以改变,子类应该覆盖这个方法。

Just provide a unique id to each fragment and you're done.

只需为每个片段提供一个唯一的 id,你就完成了。

Using a FragementStatePagerAdapteror returning POSITION_NONEin int getItemPosition (Object object)is wrong. You will not get any caching.

使用FragementStatePagerAdapter或返回POSITION_NONEint getItemPosition (Object object)是错误的。你不会得到任何缓存。

回答by Jorge Casariego

I did what @kanika and @Jraco11 had posted but I still had the problem.

我做了@kanika 和@Jraco11 发布的内容,但我仍然遇到问题。

So, after a lot of changes, I found one that worked for me and was added to my FragmentPagerAdapter the next code:

因此,经过大量更改后,我找到了一个对我有用的更改并将下一个代码添加到我的 FragmentPagerAdapter 中:

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

According to what I read, getItemPositionis used to notify the ViewPagerwhether or not to refresh an item, and to avoid updates if the items at the visible positions haven't changed.

根据我阅读的内容,getItemPosition用于通知ViewPager是否刷新项目,并在可见位置的项目未更改时避免更新。

回答by B-GangsteR

method getItem()is used only to create new items. Once they created, this method will not be called. If you need to get item that is currency in use by adapter, use this method:

方法getItem()仅用于创建新项目。一旦他们创建,这个方法将不会被调用。如果您需要获取适配器正在使用的货币项目,请使用此方法:

pagerAdapter.instantiateItem(viewPager, TAB_POS)

回答by Maddy

There are two different scenarios : 1.) You have same layout for every pager : In that case, it will be better if you'll extend your custom adapter by PagerAdapter and return a single layout.

有两种不同的情况:1.) 每个寻呼机都有相同的布局:在这种情况下,如果您通过 PagerAdapter 扩展自定义适配器并返回单个布局会更好。

2.) You have different layout for every pager : In that case, it will be better if you'll extend your custom adapter by FragmentStatePagerAdapter and return different fragmets for every pager.

2.) 每个寻呼机都有不同的布局:在这种情况下,最好通过 FragmentStatePagerAdapter 扩展自定义适配器并为每个寻呼机返回不同的片段。

回答by Oliver Dixon

I found that setting a listener on the tab-layout stopped this from being called, probably because they only have space for one listener on tabLayout.setOnTabSelectedListenerinstead of an array of listeners.

我发现在选项卡布局上设置一个侦听器阻止了它被调用,可能是因为它们只有一个侦听器的空间,tabLayout.setOnTabSelectedListener而不是一组侦听器。