方案一:ImageCycleView(LinearLayout 封裝)
核心組件
ViewPager:承載圖片頁面
ImageCycleAdapter:繼承 PagerAdapter,實現視圖復用緩存
ViewGroup 指示器容器:動態添加 ImageView 點
Handler + Runnable:5 秒定時切換
關鍵邏輯
public void setImageResources(ArrayList imageUrls, ImageCycleViewListener listener, int style) {
// 1. 清理舊指示器
mGroup.removeAllViews();
// 2. 創建指示器點
for (int i=0; i
適配器視圖復用
private class ImageCycleAdapter extends PagerAdapter {
private ArrayList cache = new ArrayList<>();
@Override public Object instantiateItem(ViewGroup container, int position) {
int resId = mAdList.get(position % mAdList.size());
SmartImageView iv = cache.isEmpty() ? new SmartImageView(mContext) : cache.remove(0);
iv.setBackgroundResource(resId);
iv.setOnClickListener(v -> mListener.onImageClick(position % mAdList.size(), v));
container.addView(iv);
return iv;
}
@Override public void destroyItem(ViewGroup container, int position, Object object) {
SmartImageView iv = (SmartImageView) object;
container.removeView(iv);
cache.add(iv);
}
@Override public int getCount() { return Integer.MAX_VALUE; }
}
方案二:PageFlipper(繼承 ViewPager,更輕量)
無限循環原理
- 數據集首尾各添加一個輔助頁(首頁複製尾頁,尾頁複製首頁)
setCurrentItem(1) 顯示真實首頁
OnPageChangeListener 中檢測到輔助頁瞬間跳轉到對應真實頁
自動輪播與觸摸控制
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == START_FLIPPING) {
if (views.size() > 3) setCurrentItem((getCurrentItem()+1) % views.size());
handler.sendEmptyMessageDelayed(START_FLIPPING, 3000);
} else if (msg.what == STOP_FLIPPING) {
handler.removeMessages(START_FLIPPING);
}
}
};
@Override public void onPageScrollStateChanged(int state) {
if (state == SCROLL_STATE_IDLE) handler.sendEmptyMessageDelayed(START_FLIPPING, 3000);
else if (state == SCROLL_STATE_DRAGGING) handler.sendEmptyMessage(STOP_FLIPPING);
}
對比選型建議
| 特性 | ImageCycleView | PageFlipper |
| 指示器樣式 | 圓點/長條可配置 | 需自行實現 |
| 視圖復用 | SmartImageView 緩存池 | 簡單 View 列表 |
| 無限循環 | Integer.MAX_VALUE/2 | 首尾輔助頁 |
| 擴展性 | 支持點擊回調、圖片加載庫 | 輕量、易定制 |