本文共 4763 字,大约阅读时间需要 15 分钟。
Viewpager的无限循环方式有两种,网上有很多现成的例子
1、第二种就是无限型,在pagerAdapter的getCount方法设置一个很大的值
①
@Override public int getCount() { return Integer.MAX_VALUE; }这个值设置的比较大就可以 , 还有好多文章设置10000、100000等。
这个方法的优点是:页面创建数量少的时候流畅,“用户”也不会一直滑动页面(用户至上ლ(′◉❥◉`ლ))。
缺点是: 配置低的手机在创建多个页面的时候会卡顿,优化方法就是将不用的页面remove掉(请自行百度)。
2、第二种就是复用型,在第一页的位置加上最后一页的数据,最后一页加上第一页的数据,用动画过渡优化加载
可以实现左右双向无限循环 。需要解决过渡动画和页面索引。
今天聊一下自定义实现的步骤
1、自定义viewPager,目的是为了实现爱奇艺Banner样式,复写Viewpager的构造器 处理setOnHierarchyChangeListener监听
public class DepthPageTransformer implements ViewPager.PageTransformer { @TargetApi(Build.VERSION_CODES.HONEYCOMB) @SuppressLint("NewApi") public void transformPage(View view, float position) { if (position < -1) { // [-Infinity,-1) view.setScaleY(minScale); view.setAlpha(minAlpha); } else if (position <= 0) { // [-1,0] float scaleFactor = minScale + (1 - minScale) * (1 - Math.abs(position)); float alphaFactor = minAlpha + (1 - minAlpha) * (1 - Math.abs(position)); view.setScaleY(scaleFactor); view.setAlpha(alphaFactor); } else if (position <= 1) { // (0,1] float scaleFactor = minScale + (1 - minScale) * (1 - Math.abs(position)); float alphaFactor = minAlpha + (1 - minAlpha) * (1 - Math.abs(position)); view.setScaleY(scaleFactor); view.setAlpha(alphaFactor); } else { // (1,+Infinity] view.setScaleY(minScale); view.setAlpha(minAlpha); } view.setAlpha(1); } }
此处定义了minScale 和minAlpha两个参数来控制左右两边的 展示部分 ,用set方法可以设置大小(这里的大小是百分比)
2、自定义轮播需要的图片和指示器(xml就不写了,需要ViewPager和LinearLayout )。
①在attrs里面写好需要自定义的属性。(左右间距、指示器位置等...我这就打住自定义View的过程了。)
②pagerAdapter的修改
@Override public Object instantiateItem(ViewGroup container, final int position) { if (creator == null) { throw new RuntimeException("[Banner] --> The layout is not specified,please set holder"); } BannerViewHolder holder = creator.createViewHolder(); View view = holder.createView(container.getContext()); container.addView(view); if (mDatas != null && mDatas.size() > 0) { holder.onBind(container.getContext(), toRealPosition(position), mDatas.get(toRealPosition(position))); } //*****主要是在pagerAdapter在中,给整个控件加上条目点击事件 if (listener != null) { view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listener.onBannerClick(toRealPosition(position)); } }); } return view; }
整个控件加上条目点击事件,实现点击事件。
③实现ViewPager的OnPageChangeListener 监听,其中的onPageSelected 方法主要写页面滑动的逻辑
@Override public void onPageSelected(int position) { currentItem = position; if (mOnPageChangeListener != null) { mOnPageChangeListener.onPageSelected(toRealPosition(position)); } if (bannerStyle == BannerConfig.CIRCLE_INDICATOR || bannerStyle == BannerConfig.CIRCLE_INDICATOR_TITLE || bannerStyle == BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE || bannerStyle == BannerConfig.CUSTOM_INDICATOR) { if (isLoop) { if (mIndicatorSelectedDrawable != null && mIndicatorUnselectedDrawable != null) { indicatorImages.get((lastPosition - 1 + count) % count).setImageDrawable(mIndicatorUnselectedDrawable); indicatorImages.get((position - 1 + count) % count).setImageDrawable(mIndicatorSelectedDrawable); } else { indicatorImages.get((lastPosition - 1 + count) % count).setImageResource(mIndicatorUnselectedResId); indicatorImages.get((position - 1 + count) % count).setImageResource(mIndicatorSelectedResId); } } else { if (mIndicatorSelectedDrawable != null && mIndicatorUnselectedDrawable != null) { indicatorImages.get((lastPosition + count) % count).setImageDrawable(mIndicatorUnselectedDrawable); indicatorImages.get((toRealPosition(position) + count) % count).setImageDrawable(mIndicatorSelectedDrawable); } else { indicatorImages.get((lastPosition + count) % count).setImageResource(mIndicatorUnselectedResId); indicatorImages.get((toRealPosition(position) + count) % count).setImageResource(mIndicatorSelectedResId); } } lastPosition = position; }}
现在做到这里基本可以实现了无限轮播,还缺少了自动滚动和 触摸时停止滚动。今天先聊这么多,毕竟码农还是要上班的。下次约。
转载地址:http://mnwsi.baihongyu.com/