Android高階圖片滾動控制元件,編寫3D版的圖片輪播器 一屏顯示多個圖片
阿新 • • 發佈:2019-02-19
大家好,好久不見了,最近由於工作特別繁忙,已經有一個多月的時間沒寫部落格了,我也是深感慚愧。那麼今天的這篇既然是闊別了一個多月的文章,當然要帶來更加給力點的內容了,那麼話不多說,趕快進入到今天的正題吧。
說到圖片輪播器,很多的Android應用中都會帶有這個功能,比如說網易新聞、淘寶等。最新我們公司的一款應用也加入了這個功能,並且在圖片輪播的基礎上還增加了三維立體的效果,但比較遺憾的是,整體效果並不理想,使用者體驗性比較糟糕。因此,我就花了點時間去編寫了一個效果更好的3D圖片輪播器,自我感覺還是比較滿意的,這裡果斷寫一篇部落格來分享給大家。
首先來介紹一下實現原理吧,傳統的圖片輪播器在一個介面上只會顯示一張圖片,要用手指進行左右滑動才能看到其它的圖片。這裡我們將思維發散一下,允許在一個介面上同時顯示三張圖片,再通過Camera的方式對左右的兩張圖進行3D旋轉,這樣就能製作出一種立體的圖片輪播器了,原理示意圖如下所示:
對圖片進行立體操作還是要使用到Camera技術,如果你對這個技術還不太熟悉,可以到網上搜一些相關資料,或者參考我前面的一篇文章:Android中軸旋轉特效實現,製作別樣的圖片瀏覽器 。
那麼我們現在就開始動手吧,首先新建一個Android專案,起名叫做ImageSwitchViewTest。
然後新建一個Image3DView繼承自ImageView,它會繼承ImageView的所有屬性,並且加入3D旋轉的功能,程式碼如下所示:
- publicclass Image3DView extends ImageView {
-
/**
- * 旋轉角度的基準值
- */
- privatestaticfinalfloat BASE_DEGREE = 50f;
- /**
- * 旋轉深度的基準值
- */
- privatestaticfinalfloat BASE_DEEP = 150f;
- private Camera mCamera;
- private Matrix mMaxtrix;
- private Bitmap mBitmap;
- /**
- * 當前圖片對應的下標
- */
-
private
- /**
- * 在前圖片在X軸方向滾動的距離
- */
- privateint mScrollX;
- /**
- * Image3DSwitchView控制元件的寬度
- */
- privateint mLayoutWidth;
- /**
- * 當前圖片的寬度
- */
- privateint mWidth;
- /**
- * 當前旋轉的角度
- */
- privatefloat mRotateDegree;
- /**
- * 旋轉的中心點
- */
- privatefloat mDx;
- /**
- * 旋轉的深度
- */
- privatefloat mDeep;
- public Image3DView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mCamera = new Camera();
- mMaxtrix = new Matrix();
- }
- /**
- * 初始化Image3DView所需要的資訊,包括圖片寬度,擷取背景圖等。
- */
- publicvoid initImageViewBitmap() {
- if (mBitmap == null) {
- setDrawingCacheEnabled(true);
- buildDrawingCache();
- mBitmap = getDrawingCache();
- }
- mLayoutWidth = Image3DSwitchView.mWidth;
- mWidth = getWidth() + Image3DSwitchView.IMAGE_PADDING * 2;
- }
- /**
- * 設定旋轉角度。
- *
- * @param index
- * 當前圖片的下標
- * @param scrollX
- * 當前圖片在X軸方向滾動的距離
- */
- publicvoid setRotateData(int index, int scrollX) {
- mIndex = index;
- mScrollX = scrollX;
- }
- /**
- * 回收當前的Bitmap物件,以釋放記憶體。
- */
- publicvoid recycleBitmap() {
- if (mBitmap != null && !mBitmap.isRecycled()) {
- mBitmap.recycle();
- }
- }
- @Override
- publicvoid setImageResource(int resId) {
- super.setImageResource(resId);
- mBitmap = null;
- initImageViewBitmap();
- }
- @Override
- publicvoid setImageBitmap(Bitmap bm) {
- super.setImageBitmap(bm);
- mBitmap = null;
- initImageViewBitmap();
- }
- @Override
- publicvoid setImageDrawable(Drawable drawable) {
- super.setImageDrawable(drawable);
- mBitmap = null;
- initImageViewBitmap();
- }
- @Override
- publicvoid setImageURI(Uri uri) {
- super.setImageURI(uri);
- mBitmap = null;
- initImageViewBitmap();
- }
- @Override
- protectedvoid onDraw(Canvas canvas) {
- if (mBitmap == null) {
- // 如果Bitmap物件還不存在,先使用父類的onDraw方法進行繪製
- super.onDraw(canvas);
- } else {
- if (isImage