自定義輪播圖(Banner)
先上圖看效果:

在這裡插入圖片描述
知識要點:
-
輪播圖是怎麼做到無限迴圈的呢
讓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一下