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
FragmentPagerAdapter getItem is not called
提问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
FragmentStatePagerAdapter
destroys as Fragments that aren't being used.FragmentPagerAdapter
does not.
这样做的原因是因为
FragmentStatePagerAdapter
销毁为未使用的 Fragment。FragmentPagerAdapter
才不是。
回答by Jraco11
Using a FragmentStatePagerAdapter
didn't fully fix my problem which was a similar issue where onCreateView
was not being called for child fragments in the view pager. I am actually nesting my FragmentPagerAdapter
inside of another Fragment
therefore the FragmentManager
was shared throughout all of them and thus retaining instances of the old fragments. The fix was to instead feed an instance of the getChildFragmentManager
to the constructor of the FragmentPagerAdapter
in my host fragment. Something like...
使用 aFragmentStatePagerAdapter
并没有完全解决我的问题,这是一个类似的问题,onCreateView
在视图寻呼机中没有被调用子片段。我实际上是将我的FragmentPagerAdapter
内部嵌套在另一个内部,Fragment
因此FragmentManager
所有这些都共享,从而保留了旧片段的实例。解决方法是将 的实例提供getChildFragmentManager
给FragmentPagerAdapter
主机片段中的的构造函数。就像是...
FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());
The getChildFragmentManager()
method is accessible via a fragment and this worked for me because it returns a private FragmentManager
for 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 atleast17 (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)
FragmentPagerAdapter
caches the fragments it creates using getItem
. I was facing the same issue- even after calling notifyDataSetChanged()
getItem
was not being called.
FragmentPagerAdapter
缓存它使用getItem
. 我面临着同样的问题 - 即使在notifyDataSetChanged()
getItem
没有被调用之后。
This is actually a feature and not a bug. You need to override getItemId
so 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 FragementStatePagerAdapter
or returning POSITION_NONE
in int getItemPosition (Object object)
is wrong. You will not get any caching.
使用FragementStatePagerAdapter
或返回POSITION_NONE
的int 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.setOnTabSelectedListener
instead of an array of listeners.
我发现在选项卡布局上设置一个侦听器阻止了它被调用,可能是因为它们只有一个侦听器的空间,tabLayout.setOnTabSelectedListener
而不是一组侦听器。