Android 圖片輪播控件

轉載請註明出處 http://blog.csdn.net/u011510784/article/details/49766099

爲方便高效開發Android項目,推出Android開發常用控件系列,提高代碼複用性,降低開發成本.

本文介紹的是Android項目中經常可以看到的廣告位圖片輪播控件,本文介紹的控件是基於網上的開源項目Viewflow寫的.
如圖:
圖片輪播'

在ViewFlow項目中的輪播不支持從第一張圖片向前滑到最後一張圖片,還需要進行一些改動.先看一下這個控件項目中所使用到的類:



ViewFlow就是自定義輪播控件;CircleFlowIndicator是自定義的指示器控件;FlowIndicator是個接口,指示器控件繼承次接口;因爲此輪播控件顯示的圖片是從網絡上獲取來的,所以用到了圖片加載框架ImageLoader,在MyApplication裏面初始化了此框架.接下來挑一些細節講解下:
首先看下MainActivity中的初始化控件:
	private void initData() {
		head_tv_content.setText("0");
		
		viewFlow.setmSideBuffer(urlsForNet.length);
		viewFlow.setFlowIndicator(CFIndic);
		viewFlow.setTimeSpan(3000);
		viewFlow.startAutoFlowTimer(); // 啓動自動播放
		viewFlow.setAdapter(new CirculateAdapter(urlsForNet));
		viewFlow.setOnViewSwitchListener(new ViewSwitchListener() {
			@Override
			public void onSwitched(View view, int position) {
				head_tv_content.setText("第" + (position+1)+"張");
			}
		});
	}
setmSideBuffer是設置輪播圖片的數量,在CirculateAdapter類中需要注意的地方是這個adapter類的getCount()方法返回了一個Integer.MAX_VALUE,以便可以保證viewFlow的循環,我們修改後的這個項目中getCount()()方法只需要返回正常position.

在ViewFlow類中它的流程是這樣的:假如需要輪播的圖片一共有三張,那麼它會初始化4張圖片,第四張放的就是第一張的圖片:
                View currentView = makeAndAddView(position, true,(recycleViews.isEmpty() ? null : recycleViews.remove(0)));
		mLoadedViews.addLast(currentView);
		for (int offset = 1; mSideBuffer - offset >= 0; offset++) {
			int leftIndex = position - offset;
			int rightIndex = position + offset;
			if (leftIndex >= 0)
				mLoadedViews.addFirst(makeAndAddView(leftIndex,false,
								(recycleViews.isEmpty() ? null : recycleViews.remove(0))));
			if (rightIndex < mAdapter.getCount())
				mLoadedViews.addLast(makeAndAddView(rightIndex, true, </span>
<span style="font-family:SimHei;font-size:14px;">                                                                (recycleViews.isEmpty() ? null : recycleViews.remove(0))));
		}
makeAndAddView()方法的作用是根據傳入的position得到adapter中相應的view,即最終會調用 adapter.getView()方法來返回一個view.在for循環之前,先添加當前position對應的圖片,因爲當前position也可能不爲0,然後再通過for循環在依次添加其他圖片.額外的一張圖片也是在這裏添加的,因爲mAdapter.getCount()返回到是Integer.MAX_VALUE,這裏的mLoadedView集合用的是LinkedList<>,方便快速的插入與刪除.到這裏圖片初始化完成,接下來是滑動,滑動的細節源代碼寫的很清楚就不在一一貼代碼了,下面看他實現循環滾動的方法:
	private void postViewSwitched(int direction) {
		if (direction == 0)
			return;
		if (direction > 0) { // to the right
			mCurrentAdapterIndex++;
			mCurrentBufferIndex++;
			View recycleView = null;
			// Remove view outside buffer range
			if (mCurrentAdapterIndex > mSideBuffer) {
				recycleView = mLoadedViews.removeFirst();
				detachViewFromParent(recycleView);
				mCurrentBufferIndex--;
			}
			// Add new view to buffer
			int newBufferIndex = mCurrentAdapterIndex + mSideBuffer;
			if (newBufferIndex < mAdapter.getCount())
				mLoadedViews.addLast(makeAndAddView(newBufferIndex, true,
						recycleView));

		} else { // to the left
			mCurrentAdapterIndex--;
			mCurrentBufferIndex--;
			View recycleView = null;
			// Remove view outside buffer range
			if (mAdapter.getCount() - 1 - mCurrentAdapterIndex > mSideBuffer) {
				recycleView = mLoadedViews.removeLast();
				detachViewFromParent(recycleView);
			}
			// Add new view to buffer
			int newBufferIndex = mCurrentAdapterIndex - mSideBuffer;
			if (newBufferIndex > -1) {
				mLoadedViews.addFirst(makeAndAddView(newBufferIndex, false,
						recycleView));
				mCurrentBufferIndex++;
			}
		}
		requestLayout();
		setVisibleView(mCurrentBufferIndex, true);
		if (mIndicator != null) {
			mIndicator.onSwitched(mLoadedViews.get(mCurrentBufferIndex),
					mCurrentAdapterIndex);
		}
		if (mViewSwitchListener != null) {
			mViewSwitchListener
					.onSwitched(mLoadedViews.get(mCurrentBufferIndex),
							mCurrentAdapterIndex);
		}
	}

這個方法中傳入的是滑動的方向,他的判斷方式是記錄當前頁面,計算將要滑動的下一個頁面,如果將要滑動的頁面號減去當前頁面號大於0,那麼認爲是正方向,小於0則是反方向.如果是正方向
判斷當前圖片頁面的索引值是否大於了輪播控件中圖片的張數,因爲這個mLoadedView集合裏存放的圖片張數比輪播控件裏的實際張數大一.如果大於了,說明已經滑動到mLoadedView集合的最後一張,也就是實際圖片的第一張了,那麼就把mLoadedView集合的第一張去掉,新加一張圖片,也就是實際圖片的第二張,方向相反一個道理.這樣就實現了圖片的輪播,但是這樣在顯示第一張圖片的情況下是不能滑動到最後一張的,接下來我們修改一下.

大體流程是這樣的:初始化這個輪播控件的時候,在mLoadedView集合裏面多加兩個圖片,即在最前面加一張最後那個圖片,在最後面加一張第一張那個圖片,原來是1,2,3 現在是 3_,1,2,3,1_. 在滑動到1_時候把相應的位置重置成1,將圖片也滑動到1位置,一個道理,當向後滑到3_時,將其信息重置成3,這樣在第一張圖片的情況下也可以向後滑動了.
	private void postViewSwitched(int direction) {
		if (direction == 0)
			return;
		if (direction > 0) { // to the right
			if (mCurrentScreen == mSideBuffer + 1) {
				mCurrentAdapterIndex = -1;
				mCurrentBufferIndex = 0;
				mCurrentScreen = 1;
			}
			mCurrentAdapterIndex++;
			mCurrentBufferIndex++;

		} else { // to the left
			if (mCurrentScreen == 0) {
				mCurrentAdapterIndex = mSideBuffer;
				mCurrentBufferIndex = mSideBuffer + 1;
				mCurrentScreen = mSideBuffer;
			}
			mCurrentAdapterIndex--;
			mCurrentBufferIndex--;

		}
		requestLayout();
		setVisibleView(mCurrentBufferIndex, true);
		if (mIndicator != null) {
			mIndicator.onSwitched(mLoadedViews.get(mCurrentBufferIndex),
					mCurrentAdapterIndex);
		}
		if (mViewSwitchListener != null) {
			mViewSwitchListener
					.onSwitched(mLoadedViews.get(mCurrentBufferIndex),
							mCurrentAdapterIndex);
		}
	}
當然裏面還有很多的細節處理,具體見源碼吧!






















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章