FragmentStatePagerAdapter onPageSelected事件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FragmentStatePagerAdapter onPageSelected事件相关的知识,希望对你有一定的参考价值。
我有一个FragmentStatePagerAdapter,里面有6个片段。
每个Fragment连接到服务器并加载数据。
现在,服务器连接正在Fragment.onStart()中完成,这意味着在任何时候,我都有3个http请求(选定的片段,每侧一个)。
我想要的是当时只有一个连接,所以我打算使用
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener()
{
@Override
public void onPageSelected(final int position)
{
CustomFragment fragment = (CustomFragment) myFragmentStatePagerAdapter.getItem(position);
fragment.onSelected();//do stuff in here
}
});
问题是,getItem()
返回片段的新实例,尚未添加到管理器中(因此,尚未创建视图等)。
此外,我已经尝试过setUserVisibleHint(boolean isVisibleToUser)
但是没有被调用可见,仅在isVisibleToUser = false
那么,如何为Fragment实现“onPageSelected()”事件呢?
提前致谢
对你来说最好的解决方案是覆盖setUserVisibleHint()
。确保你扩展FragmentPagerAdapter
。从它的source code你可以看到它也称为setUserVisibleHint(true)
可见碎片。我一直使用它,效果很好。
// adapter
public static class PlayerAdapter extends FragmentStatePagerAdapter {
public PlayerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return 6;
}
@Override
public Fragment getItem(int position) {
return new SimpleFragment();
}
}
// fragment
public class SimpleFragment extends Fragment {
private static final String TAG = BookControlsFragment.class.getSimpleName();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_simple, container, false);
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
Log.d(TAG, "setUserVisibleHint: " + isVisibleToUser);
}
}
对我来说有用的是,在我的寻呼机适配器的getItem
方法中,在列表中保存我自己对我返回的自定义片段的引用。片段寻呼机适配器和片段状态寻呼机适配器似乎遵循的合同意味着getItem(i)
返回的最后一个片段将是在onPageSelected(i)
方法中刷新的正确片段。
我只使用片段寻呼机适配器和相当少数量的选项卡测试了这种技术。使用状态寻呼机适配器,需要进行一些测试,以查看是否保持对片段的引用会导致内存使用增加。
在你的FragmentStatePagerAdapter
中使用HashMap
来保存创建的Fragments,然后你可以从viewpager容器(活动或片段)访问它们:
public class CustomFragmentPagerAdapter extends FragmentStatePagerAdapter {
private HashMap<Integer, CustomFragment> fragMap =
new HashMap<Integer, CustomFragment>();
...
@Override
public Fragment getItem(int position) {
CustomFragment frag = new CustomFragment();
...
fragMap.put(position, frag);
return frag;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
fragMap.remove(position);
}
public CustomFragment getFragment(int position) {
return fragMap.get(position);
}
...
}
现在,在viewpager容器(活动或片段)中:
private int lastPage = 0;
...
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
CustomFragment fragment;
int currentPage = viewPager.getCurrentItem();
/* connect the current fragment and disconnect the previous one, in case
you actually need to disconnect it from the server,
otherwise just connect the current fragment.*/
if(currentPage > lastPage) {
fragment = yourPagerAdapter.getFragment(currentPage - 1);
fragment.disconnect();
fragment = yourPagerAdapter.getFragment(currentPage);
fragment.connect();
} else {
fragment = yourPagerAdapter.getFragment(currentPage + 1);
fragment.disconnect();
fragment = yourPagerAdapter.getFragment(currentPage);
fragment.connect();
}
lastPage = currentPage;
}
});
由于在启动应用程序时未调用onPageChangeListener,因此您需要连接第一个片段。重要的是你将使用getItem()
引用yourPagerAdapter.getFragment(currentPage)
返回的碎片。
编辑:
我认为这可能是onPageSelected()
回调方法的更好逻辑:
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
CustomFragment fragment;
int currentPage = viewPager.getCurrentItem();
Set<Integer> myKeySet = yourPagerAdapter.getKeys();
for(Integer key : myKeySet) {
if(key == currentPage) {
fragment = yourPagerAdapter.getFragment(key);
fragment.connect();
} else {
fragment = yourPagerAdapter.getFragment(key);
fragment.disconnect();
}
}
}
});
但是你需要在qazxsw poi上实现这个方法:
FragmentStatePagerAdapter
并摆脱public Set<Integer> getKeys() {
return fragMap.keySet();
}
数据成员。
火车晚了。从根本上说,这种方法都不是我最喜欢的。他们很hacky。最好的方法是使用适配器lastPage
在setPrimaryItem(ViewGroup container, int position, Object object)
onPageSelected里面(最终的int位置)`
代码示例是这样的,
setPrimaryItem' save the current Fragment and use it inside
以上是关于FragmentStatePagerAdapter onPageSelected事件的主要内容,如果未能解决你的问题,请参考以下文章
FragmentStatePagerAdapter 向 TextView 返回错误的位置
如何将 FragmentFactory 与 FragmentStatePagerAdapter 一起使用
getItem 函数在 FragmentStatePagerAdapter 中调用两次?
FragmentPagerAdapter和FragmentStatePagerAdapter区别?