Android 滑動效果基礎篇(三)—— Gallery仿映像集瀏覽

來源:互聯網
上載者:User

Android系統內建一個Gallery瀏覽圖片的應用,通過手指拖動時能夠非常流暢的顯示圖片,使用者互動和體驗都很好。

本樣本就是通過Gallery和自訂的View,模仿實現一個仿Gallery映像集的圖片瀏覽效果。如下:

1、基本原理

在 Activity 中實現 OnGestureListener 的介面 onFling() 手勢事件,通過自訂的 View 繪製draw() 圖片

2、Activity

Activity中,通過onTouchEvent() 註冊 myGesture.onTouchEvent(event)

@Override<br />public boolean onTouchEvent(MotionEvent event) {<br />switch (event.getAction()) {<br />case MotionEvent.ACTION_UP:<br />flingView.onFling(0);// 手指抬起後,重設滑動距離offsetX = 0<br />break;<br />}</p><p>return myGesture.onTouchEvent(event);<br />}

接著實現介面OnGestureListener 的 onScroll()方法,給繼承自View的 FlingView 的handleScroll()成員方法傳遞滑動參數,擷取滑動的x軸距離

@Override<br />public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {<br />flingView.handleScroll(-1 * (int) distanceX);<br />return true;<br />}

接著實現介面OnGestureListener 的 OnFling()方法,給繼承自View的 FlingView 的onFling()成員方法傳遞滑動參數,擷取手勢的速度

@Override<br />public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {<br />flingView.onFling((int) - velocityX);<br />return true;<br />}

3、FlingView

FlingView中,擷取來自Activity中的手勢速度

public void onFling(int paramFloat1) {<br />if (offsetX > GalleryDemoActivity.deviceScreenWidth / 5) {<br />if (fBitmap != null) {<br />isFling = true;<br />isFlingRight = true;<br />}<br />} else if (offsetX < -GalleryDemoActivity.deviceScreenWidth / 5) {<br />if (nBitmap != null) {<br />isFling = true;<br />isFlingLeft = true;<br />}<br />}<br />// 開始動畫效果<br />startAnimation(new MyAnimation());<br />}

在滑動過程中,通過實現View的Draw()方法繪製圖片,注意:此時需要同時繪製當前圖片(擷取焦點)和下一張圖片(即將擷取焦點)共兩張圖片

@Override<br />public void draw(Canvas canvas) {<br />Paint paint = new Paint();<br />Rect rect = new Rect();<br />canvas.drawColor(Color.BLACK);</p><p>// 繪製當前圖片<br />if (bitmap != null) {<br />int left = offsetX;<br />int top = offsetY;<br />int right = offsetX + GalleryDemoActivity.deviceScreenWidth;<br />int bottom = offsetY + GalleryDemoActivity.deviceScreenHeight;<br />rect.set(left, top, right, bottom);<br />canvas.drawBitmap(bitmap, null, rect, paint);<br />}</p><p>// 繪製下一張圖片<br />if (offsetX < 0) {// 向左滑動<br />if (nBitmap != null) {<br />int left = GalleryDemoActivity.deviceScreenWidth + 15 + offsetX;<br />int top = 0;<br />int right = left + GalleryDemoActivity.deviceScreenWidth;<br />int bottom = GalleryDemoActivity.deviceScreenHeight;<br />rect.set(left, top, right, bottom);<br />canvas.drawBitmap(nBitmap, null, rect, paint);<br />}<br />} else if (offsetX > 0) {// 向右滑動<br />if (fBitmap != null) {<br />int left = -GalleryDemoActivity.deviceScreenWidth - 15 + offsetX;<br />int top = 0;<br />int right = left + GalleryDemoActivity.deviceScreenWidth;<br />int bottom = GalleryDemoActivity.deviceScreenHeight;<br />rect.set(left, top, right, bottom);<br />canvas.drawBitmap(fBitmap, null, rect, paint);<br />}<br />}<br />}在滑動圖片結束後,需要做滑動動畫後的處理,重新設定當前圖片和當前圖片的上一張和下一張的狀態,為下次滑動做準備

@Override<br />protected void onAnimationEnd() {<br />if (isFlingRight) {// 向右滑動,position減1<br />nBitmap = bitmap;<br />bitmap = fBitmap;<br />fBitmap = null;<br />postion = postion - 1;<br />} else if (isFlingLeft) {// 向左滑動,position加1<br />fBitmap = bitmap;<br />bitmap = nBitmap;<br />nBitmap = null;<br />postion = postion + 1;<br />}</p><p>isFlingRight = false;<br />isFlingLeft = false;<br />isFling = false;<br />offsetX = 0;<br />if (fBitmap == null && offsetX == 0) {// 如果前一張圖片為空白(向右滑),則重設前一張圖片(position - 1)<br />if (postion > 0) {<br />fBitmap = getBitmap(postion - 1);<br />}</p><p>} else if (nBitmap == null && offsetX == 0) {// 如果後一張圖片為空白(向左滑),則重設後一張圖片(position + 1)<br />if (postion < bitmaps.length - 1) {<br />nBitmap = getBitmap(postion + 1);<br />}<br />}<br />clearAnimation();<br />}

4、手勢座標介紹

本樣本中,用到了OnGestureListener介面的onScroll()和OnFling()方法,涉及到了Android系統座標及觸摸MotionEvent e1和e2、速度velocityX、velocityY等值

Android螢幕座標系如(左)

(1)MotionEvent中 e1是手指第一次按上螢幕的起點,e2是抬起手指離開螢幕的終點,根據Android螢幕座標系可知:

手指向右滑動,終點(e2)在起點(e1)的右側,有e2.getX() - e1.getX() 大於0
手指向左滑動,終點(e2)在起點(e1)的左側,有e2.getX() - e1.getX() 小於0
手指向下滑動,終點(e2)在起點(e1)的下側,有e2.getY() - e1.getY() 大於0
手指向上滑動,終點(e2)在起點(e1)的上側,有e2.getY() - e1.getY() 小於0

(2)onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)

distanceX,是前後兩次call的X距離,不是e2與e1的水平距離

distanceX,是前後兩次call的Y距離,不是e2與e1的垂直距離

具體數值的方向,請詳見(中)

(3)onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) 

velocityX,是X軸的每秒速度

velocityY,是Y軸的每秒速度

具體數值的方向,請詳見(右)

仔細觀察可以發現:velocityX、velocityY的方向與distanceX、distanceY方向正好相反

更多OnGestureListener介面函數介紹,請見上一篇部落格 Android 滑動效果入門篇(一)—— ViewFlipper

樣本源碼下載

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.