自定义轮播图(Banner)
2019-03-11 本文已影响14人
元创造力
先上图看效果:
在这里插入图片描述
知识要点:
-
轮播图是怎么做到无限循环的呢
让ViewPagerAdapter里面的getCount返回MAX_VALUE,instantiateItem方法中,获取图片的时候,让position % drawableList.size(),来得到真实值@Override public int getCount() { return Integer.MAX_VALUE; } @NonNull @Override public Object instantiateItem(@NonNull ViewGroup container, int position) { if (drawableList != null && drawableList.size() > 0) { View imageView = null; if (mCache.isEmpty()) { imageView = new ImageView(mContext); }else { imageView = mCache.remove(0); } ((ImageView) imageView).setImageDrawable(drawableList.get(position % drawableList.size())); container.addView(imageView); return imageView; } return null; }
-
自动轮播是怎么实现的呢
通过Handler每隔一段时间发送一次消息,来进行循环的,每循环一次,就切换到下一个ViewPager的位置@Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == MSG_CHANGE_SELECTION) { if (mBannerRef == null || mBannerRef.get() == null) { return; } AutoScrollViewPager banner = mBannerRef.get(); int current = banner.getCurrentItem(); banner.setCurrentItem(current + 1); sendEmptyMessageDelayed(MSG_CHANGE_SELECTION,AUTO_SCROLL_TIME); } }
-
指示器是怎么实现的
首先自定义一个BannerItemView,代表每个小圆点,再自定义个BannerIndicator,把总共的小圆点添加进去,通过伸缩动画和透明度动画来改变小圆点的变化//指示器增大同时设置透明度变化 private void setLarge(int position) { if (getChildAt(position) instanceof BannerItemView) { AnimatorSet set = new AnimatorSet(); ValueAnimator animator = getEnlarge((BannerItemView) getChildAt(position)); ValueAnimator alpha = ObjectAnimator.ofFloat(getChildAt(position), "alpha", 0.4f, 1f); set.play(animator).with(alpha); set.setDuration(618); set.start(); } } //放大动画 private ValueAnimator getEnlarge(BannerItemView roundRectView) { return ObjectAnimator.ofFloat(roundRectView, "rectWidth", 0, getOffset(roundRectView)); } //根据大小变化方向获取指示器大小偏移量 private int getOffset(BannerItemView bannerItemView) { int offsest = 0; switch (bannerItemView.getLoaction()) { case BannerItemView.CENTER: offsest = (slider_width - slider_height)/2; break; case BannerItemView.LEFT: offsest = slider_width - slider_height; break; case BannerItemView.RIGHT: offsest = slider_width - slider_height; break; } return offsest; } //缩小动画 private ValueAnimator getShrink(BannerItemView roundRectView) { return ObjectAnimator.ofFloat(roundRectView, "rectWidth", getOffset(roundRectView), 0); } //缩小动画同事伴随透明度变化 public void setSmall(int small) { if (getChildAt(small) instanceof BannerItemView) { AnimatorSet set = new AnimatorSet(); ValueAnimator alpha = ObjectAnimator.ofFloat(getChildAt(position), "alpha", 1, 0.4f); ValueAnimator animator = getShrink((BannerItemView) getChildAt(small)); set.play(animator).with(alpha); set.setDuration(618); set.start(); } }
具体实现细节请移步github
https://github.com/xinhuashi/CustomBanner.git
如果感觉有所帮助,请帮忙star一下
参考了这两位大神的文章 https://www.jianshu.com/p/489b77424b63
https://www.jianshu.com/p/ef6ff245ed3e,在这里表示感谢