之前在做無限輪播的時候一直在使用ViewPager可能是我比較守舊的緣故吧,一直到這幾天又要實現此項功能了,聽朋友說BannerView特別好用并且是真正意義上的無限輪播,再也不是之前的Integer.MAX了,感覺挺好的所以就拿來研究了一下,實現了這個功能,可能會有些凌亂的地方,僅供大家參考,如果大家有什么好的建議可以給我留言我一定改正。
不多說了直接上代碼
首先是布局
<com.chenantao.autolayout.AutoRelativeLayout android:id="@+id/find_all_viewpager" android:layout_width="match_parent" android:layout_height="550px" > <ImageView android:id="@+id/main_cycleView_Img" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="fitXY" android:src="@mipmap/bannerdefault" android:visibility="visible" /> <com.innospace.view.ImageCycleView android:id="@+id/find_cycleView" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <LinearLayout android:id="@+id/all_dots" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignBottom="@id/main_cycleView_Img" android:layout_marginBottom="10dp" android:gravity="center" android:orientation="horizontal"></LinearLayout> </com.chenantao.autolayout.AutoRelativeLayout>然后我只貼出與實現此功能相關的大家能用到的代碼,有些代碼因項目不同貼出來也不見得能用,所以還需大家自行編寫。
首先就是網絡請求數據,這個不進行張貼,各項目有所不同,拿到數據后將數據傳遞到Handler 進行更新UI的操作,下面是Handler中要實現的代碼
bannerList.clear();bannerList.addAll(list);find_cycleView.setImageResources(bannerList, mAdCycleViewListener);if (list != null && list.size() != 0) { nodata_banaImg.setVisibility(View.GONE); find_cycleView.setVisibility(View.VISIBLE);} else { nodata_banaImg.setVisibility(View.VISIBLE); find_cycleView.setVisibility(View.GONE);}代碼很簡單,無非就是控制該控件的顯示和隱藏罷了,這里不做過多的解釋,但是注意
find_cycleView.setImageResources(bannerList, mAdCycleViewListener);代碼中mAdCycleViewListener 這個下面馬上張貼出來ImageCycleView.ImageCycleViewListener mAdCycleViewListener = new ImageCycleView.ImageCycleViewListener() { @Override public void onImageClick(BannerDao info, int postion, View imageView) { if (!isNetworkConnected()) { if (toast == null) { toast = Toast .makeText(context, "網絡不可用", Toast.LENGTH_SHORT); } else { toast.cancel();// 關閉吐司顯示 toast = Toast .makeText(context, "網絡不可用", Toast.LENGTH_SHORT); } toast.show(); } else { Intent intent = new Intent(context, ActionDetailActivity.class); MyLog.e(context, "BannarDao:" + info.toString()); MyLog.e(context, "id:" + info.getRelatedId()); id = info.getRelatedId(); int jumpType = 0; intent.putExtra("id", info.getRelatedId() + ""); intent.putExtra("index", "1"); intent.putExtra("type", info.getType()); intent.putExtra("title", info.getTitle()); intent.putExtra("picPath", info.getPicPath()); // intent.putExtra("url", info.getUrl()); System.out.PRintln("要傳遞的banner類型是::" + info.getType()); intent.putExtra("jumpType", jumpType); if (info.getUrl() != null && !info.getUrl().equals("")) { intent.putExtra("url", info.getUrl()); } startActivity(intent); } } @Override public void displayImage(String imageURL, ImageView imageView) { ImageListener imageListener = ImageLoader.getImageListener( imageView, R.mipmap.bannerdefault, R.mipmap.bannerdefault); mImageLoader.get(imageURL, imageListener); }};這里的代碼由于項目需要寫的太亂,還有好多是在打印Log也沒有進行刪除,大家將就著看看,功能能夠實現才是最重要的。
下面最重要的代碼來了,為了讓大家看清我把這個類中所有的代碼全都貼出來:
/** * 廣告圖片自動輪播控件</br> * * <pre> * 集合ViewPager和指示器的一個輪播控件,主要用于一般常見的廣告圖片輪播,具有自動輪播和手動輪播功能 * 使用:只需在xml文件中使用{@code <com.minking.imagecycleview.ImageCycleView/>} , * 然后在頁面中調用 {@link #setImageResources(ArrayList, ImageCycleViewListener) }即可! * * 另外提供{@link #startImageCycle() } / {@link #pushImageCycle() }兩種方法,用于在Activity不可見之時節省資源; * 因為自動輪播需要進行控制,有利于內存管理 * </pre> * */public class ImageCycleView extends LinearLayout { /** * 上下文 */ private Context mContext; /** * 圖片輪播視圖 */ private CycleViewPager mBannerPager = null; /** * 滾動圖片視圖適配器 */ private ImageCycleAdapter mAdvAdapter; /** * 圖片輪播指示器控件 */ private ViewGroup mGroup; /** * 圖片輪播指示器-個圖 */ private ImageView mImageView = null; /** * 滾動圖片指示器-視圖列表 */ private ImageView[] mImageViews = null; /** * 圖片滾動當前圖片下標 */ private int mImageIndex = 1; /** * 手機密度 */ private float mScale; /** * @param context */ public ImageCycleView(Context context) { super(context); } /** * @param context * @param attrs */ public ImageCycleView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mScale = context.getResources().getDisplayMetrics().density; LayoutInflater.from(context) .inflate(R.layout.view_banner_content, this); mBannerPager = (CycleViewPager) findViewById(R.id.pager_banner); mBannerPager.setOnPageChangeListener(new GuidePageChangeListener()); mBannerPager.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_UP: // 開始圖片滾動 startImageTimerTask(); break; default: // 停止圖片滾動 stopImageTimerTask(); break; } return false; } }); // 滾動圖片右下指示器視圖 mGroup = (ViewGroup) findViewById(R.id.viewGroup); } /** * 裝填圖片數據 * imageUrlList * @param * @param imageCycleViewListener */ public void setImageResources(ArrayList<BannerDao> infoList, ImageCycleViewListener imageCycleViewListener) { // 清除所有子視圖 mGroup.removeAllViews(); // 圖片廣告數量 // final int imageCount = infoList.size(); final int imageCount = infoList.size(); mImageViews = new ImageView[imageCount]; for (int i = 0; i < imageCount; i++) { mImageView = new ImageView(mContext); int imageParams = (int) (mScale * 7);// XP與DP轉換,適應不同分辨率 int imagePadding = (int) (mScale * 2.5); LayoutParams layout = new LayoutParams( imageParams, imageParams); layout.setMargins(imagePadding, 0, imagePadding, 0); mImageView.setLayoutParams(layout); mImageViews[i] = mImageView; if (i == 0) { mImageViews[i].setBackgroundResource(R.drawable.point_focused); } else { mImageViews[i] .setBackgroundResource(R.drawable.point_unfocused); } mGroup.addView(mImageViews[i]); } mAdvAdapter = new ImageCycleAdapter(mContext, infoList, imageCycleViewListener); mBannerPager.setAdapter(mAdvAdapter); startImageTimerTask(); } /** * 開始輪播(手動控制自動輪播與否,便于資源控制) */ public void startImageCycle() { startImageTimerTask(); } /** * 暫停輪播——用于節省資源 */ public void pushImageCycle() { stopImageTimerTask(); } /** * 開始圖片滾動任務 */ private void startImageTimerTask() { stopImageTimerTask(); // 圖片每3秒滾動一次 mHandler.postDelayed(mImageTimerTask, 3000); } /** * 停止圖片滾動任務 */ private void stopImageTimerTask() { mHandler.removeCallbacks(mImageTimerTask); } private Handler mHandler = new Handler(); /** * 圖片自動輪播Task */ private Runnable mImageTimerTask = new Runnable() { @Override public void run() { if (mImageViews != null) { // 下標等于圖片列表長度說明已滾動到最后一張圖片,重置下標 if ((mImageIndex++) == mImageViews.length+1) { mImageIndex = 1; } mBannerPager.setCurrentItem(mImageIndex); } } }; /** * 輪播圖片狀態監聽器 * * @author minking */ private final class GuidePageChangeListener implements OnPageChangeListener { @Override public void onPageScrollStateChanged(int state) { if (state == ViewPager.SCROLL_STATE_IDLE) startImageTimerTask(); // 開始下次計時 } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int index) { if (index == 0 || index == mImageViews.length + 1) { return; } // 設置圖片滾動指示器背景 mImageIndex = index; index -= 1; mImageViews[index].setBackgroundResource(R.drawable.point_focused); for (int i = 0; i < mImageViews.length; i++) { if (index != i) { mImageViews[i] .setBackgroundResource(R.drawable.point_unfocused); } } } } private class ImageCycleAdapter extends PagerAdapter { /** * 圖片視圖緩存列表 */ private ArrayList<ImageView> mImageViewCacheList; /** * 圖片資源列表 */ private ArrayList<BannerDao> mAdList = new ArrayList<BannerDao>(); /** * 廣告圖片點擊監聽器 */ private ImageCycleViewListener mImageCycleViewListener; private Context mContext; public ImageCycleAdapter(Context context, ArrayList<BannerDao> adList, ImageCycleViewListener imageCycleViewListener) { mContext = context; mAdList = adList; mImageCycleViewListener = imageCycleViewListener; mImageViewCacheList = new ArrayList<ImageView>(); } @Override public int getCount() { return mAdList.size(); } @Override public boolean isViewFromObject(View view, Object obj) { return view == obj; } @Override public Object instantiateItem(ViewGroup container, final int position) { String imageUrl = mAdList.get(position).getPicPath(); ImageView imageView = null; if (mImageViewCacheList.isEmpty()) { imageView = new ImageView(mContext); imageView.setLayoutParams(new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); imageView.setScaleType(ImageView.ScaleType.FIT_XY); } else { imageView = mImageViewCacheList.remove(0); } // 設置圖片點擊監聽 imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { System.out.println("這里點擊的圖片的游標是::" + mAdList.get(position).getRelatedId()); System.out.println("圖片集合的長度是是::" + mAdList.size()); mImageCycleViewListener.onImageClick(mAdList.get(position), position, v); } }); imageView.setTag(imageUrl); container.addView(imageView); mImageCycleViewListener.displayImage(imageUrl, imageView); return imageView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { ImageView view = (ImageView) object; container.removeView(view); mImageViewCacheList.add(view); } } /** * 輪播控件的監聽事件 * * @author minking */ public static interface ImageCycleViewListener { /** * 加載圖片資源 * * @param imageURL * @param imageView */ public void displayImage(String imageURL, ImageView imageView); /** * 單擊圖片事件 * position * @param * @param imageView */ public void onImageClick(BannerDao info, int postion, View imageView); }}這里有必要說一下,我在實現輪播的時候出現了這樣一個問題,就是在幾張圖片完整的輪播一遍之后會有快速顯示所有圖片然后才去加載第一張的現象(Bug),不過大家不用擔心,這個代碼是改好了的,現在我就來說一說我改動的地方,在大概195行的位置(哦,sorry這貌似沒有行標),不過沒關系好在我有注釋,是圖片自動輪播Task中這幾行代碼
if((mImageViews++)==mImageViews.length+1){
mImageIndex=1;
}
在這幾行中之前的代碼是++mImageViews,所以出現了上述情況,雖然現在解決了但是至今我也不太清楚為什么要這么改,如果有知道的童鞋希望大家給我留言哈
,好了今天就先寫到這里吧,以后有什么值得分享的一定還會貼出來的。
新聞熱點
疑難解答