Viewpager实现类似网易新闻的效果

来源:互联网 发布:大众点评数据 编辑:程序博客网 时间:2024/06/02 14:30

1、添加Adapter

public class NewsFragmentPagerAdapter extends FragmentPagerAdapter {    private static final String TAG ="PagerAdapter";private ArrayList<Fragment> fragments;private FragmentManager fm;private List<ChannelItem> userChannels;private ArrayList<Boolean> fragmentsUpdateFlag=new ArrayList<>();public NewsFragmentPagerAdapter(FragmentManager fm) {super(fm);this.fm = fm;}public NewsFragmentPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments, List<ChannelItem> userChannels) {super(fm);this.fm = fm;this.fragments = fragments;initFlag();this.userChannels =userChannels;}/** * 初始化更新标志位 */private void initFlag() {for (int i = 0; i < fragments.size(); i++) {fragmentsUpdateFlag.add(false);//初始化 都不需要更新}}@Overridepublic int getCount() {return fragments.size();}/** * @param position * @return 艹 调用notifyDatasetChange getItem方法并没有被调用 */@Overridepublic Fragment getItem(int position) {Log.e(TAG,"getItem()被调用:"+position);return fragments.get(position);}/** * 如果 Item 的位置如果没有发生变化,则返回 POSITION_UNCHANGED。 * 如果返回了 POSITION_NONE,表示该位置的 Item 已经不存在了。 * 默认的实现是假设 Item 的位置永远不会发生变化,而返回 POSITION_UNCHANGED,所以notifyXXXX没有起作用 * @param object * @return */@Overridepublic int getItemPosition(Object object) {return POSITION_NONE;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {super.destroyItem(container, position, object);}/** * Viewpager 的刷新过程是这样的,在每次调用 PagerAdapter 的 notifyDataSetChanged() 方法时,都会激活 getItemPosition(Object object) 方法, * 该方法会遍历 ViewPager 的所有 Item(由缓存的 Item 数量决定,默认为当前页和其左右加起来共3页,这个可以自行设定,但是至少会缓存2页), * 为每个 Item 返回一个状态值(POSITION_NONE/POSITION_UNCHANGED), * 如果是 POSITION_NONE,那么该 Item 会被 destroyItem(ViewGroup container, int position, Object object) 方法 remove 掉,然后重新加载, * 如果是 POSITION_UNCHANGED,就不会重新加载,默认是 POSITION_UNCHANGED, * 所以如果不重写 getItemPosition(Object object),修改返回值,就无法看到 notifyDataSetChanged() 的刷新效果。 * @param currentfrags 在这里将所有的Fragment都移除了,貌似不太好吧 */public void setFragments(ArrayList<Fragment> currentfrags,List<ChannelItem> currentChannels) {/** * 这里可以确定哪些需要改变的么? * 这里的条数 以新的Fragment为主 * */if(currentChannels.size()>=userChannels.size()){for (int i = 0; i < userChannels.size(); i++) {if (userChannels.get(i).getId()==currentChannels.get(i).getId()){fragmentsUpdateFlag.set(i, false);//如果相同 就不需要更新了}else {fragmentsUpdateFlag.set(i,true);//如果不同 就更新}}for (int i = userChannels.size(); i < currentChannels.size(); i++) {fragmentsUpdateFlag.add(i,true);//多出来的部分都要更新}}else {//如果栏目减少了,多出来的部分就不用管了for (int i = 0; i < currentChannels.size(); i++) {if (userChannels.get(i).getId()==currentChannels.get(i).getId()){fragmentsUpdateFlag.set(i,false);//如果相同 就不需要更新了}else {fragmentsUpdateFlag.set(i,true);//如果不同 就更新}}}//更新集合fragments = currentfrags;userChannels=currentChannels;notifyDataSetChanged();}/** * @param container * @param position * @return */@Overridepublic Object instantiateItem(ViewGroup container, final int position) {/*Object obj = super.instantiateItem(container, position);return obj;*///得到缓存的fragmentFragment fragment = (Fragment) super.instantiateItem(container, position);//得到tag,这点很重要String fragmentTag = fragment.getTag();if (fragmentsUpdateFlag.get(position % getCount())) {//如果这个fragment需要更新FragmentTransaction ft = fm.beginTransaction();//移除旧的fragmentft.remove(fragment);//换成新的fragmentfragment = fragments.get(position % getCount());//添加新fragment时必须用前面获得的tag,这点很重要ft.add(container.getId(), fragment, fragmentTag);ft.attach(fragment);ft.commitAllowingStateLoss();//复位更新标志fragmentsUpdateFlag.set(position % getCount(),false);}return fragment;}@Overridepublic CharSequence getPageTitle(int position) {return userChannels.get(position).getName();}


2、Viewpager填充Adapter

    homeViewPager = (ViewPager) view.findViewById(R.id.homepager_menu_detail);        pagerAdapter = new NewsFragmentPagerAdapter(mContext.getSupportFragmentManager(),fragments,userChannels);        homeViewPager.setAdapter(pagerAdapter);

3、填充效果


4、滑动tab页 Fragment加载顺序

从头条滑动到主题页面:
08-08 17:05:33.464 15970-15970图片的 onCreate()执行08-08 17:05:33.464 15970-15970图片onCreateView()执行
从专题页滑动到图片页面:
08-08 17:07:08.344 15970-15970 原创的 onCreate()执行08-08 17:07:08.344 15970-15970 原创onCreateView()执行
规律:viewPager会预加载下 一页的数据

当所有页面都create一遍后,viewpager预加载下一页只会调用onCreateView方法:
08-08 17:08:18.744 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 原创onCreateView()执行08-08 17:08:20.184 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 图片onCreateView()执行08-08 17:08:23.914 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 专题onCreateView()执行08-08 17:08:26.854 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 头条onCreateView()执行08-08 17:08:31.974 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 图片onCreateView()执行08-08 17:08:33.984 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 原创onCreateView()执行08-08 17:08:35.314 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 本地onCreateView()执行08-08 17:08:38.994 15970-15970/cn.com.zgsyb.oil E/BaseFragment: 培训onCreateView()执行


5、需要解决的问题

5.1消除预加载(显示界面的时候再加载数据)


5.2跳转页面顺序,刷新数据





0 0