1. 程式人生 > >android 自定義ImageView實現圖片手勢滑動 多點觸控放大縮小效果

android 自定義ImageView實現圖片手勢滑動 多點觸控放大縮小效果

               

轉自:http://blog.csdn.net/jj120522/article/details/8467810

首先呢,還是一貫作風,我們先來看看眾多應用中的示例:(這種效果是很常見的,可以說應用的必須品.)

              

             搜狐客戶端                                    百度新聞客戶端                              新浪微博                              鳳凰新聞客戶端

也許大家對這些客戶端並不陌生,但是不知道大家有沒有注意到這些不足之處呢,這裡我就叨嘮嚇這些不人性化的地方.

首先搜狐:

她的圖片放大後(未鋪滿螢幕)可以上下來回拖動,這點肯定是不允許的.感慨搜狐你在移動新聞界這麼有名氣,莫非是故意如此嗎?

百度客戶端:你看她的圖片不用我多說了吧,其實我還可以繼續在縮,這裡我要狠狠批判一下百度,因為你那麼牛叉的公司,為什麼這點bug就查不出來,使用者體驗相當不好.

新浪微博:她的圖片可以縮放到這個程度,沒有回縮動畫,我個人感覺最好有回縮動畫的,畢竟使用者不可能看你家圖的時候將之縮放成小圖看吧.(或許使用者在放大後想縮回原先圖片而此時縮回頭了,所以我們應該弄一個回縮動畫.)

鳳凰新聞客戶端: 這家應用更離譜,就沒有放大縮小等操作,就一個傻傻的圖片呆在那,更離譜的是我(無意)觸碰一下圖片就返回了.(我要是使用者的話,就先不說你家沒有放大縮小等操作吧,倘若我想仔細觀看這張美圖的話,我手指不小心觸碰一下,你Y的就給我關閉.大失雅興,還有就是我點選文章圖片切換到瀏覽圖片頁面時,你的載入頁面太醜了,我簡直看不下去,所以果斷卸掉.)

其實網上也有幾個做的比較好的,我沒有上圖,例如:騰訊微博,網易客戶端,新浪微博等.做的都相當不錯。

哈哈.說的有點過了,就叨嘮到此,下面我們看下應該如何實現這種效果.說之前我在絮叨一下,這篇文章本來是打算2012.12.31釋出的留個紀念,誰知這玩意我弄了一天沒有弄出來,後來放棄了,長時間沒有弄出來心情也沒有了,直到2013.01.04也就是昨天又接著弄了將近一天,到晚上11點了還沒有解決.一怒之下CF玩到1點睡覺去了.該死的破玩意想留個紀念也不讓.今天下午有時間就又接著搞.功夫不負有心人啊.沒想到解決了.我鬱悶了個去.所以這篇文章來之不易啊,如果看到該文章並且對你有幫助的話,記得贊一個.

網上文章雖多,但是這種效果少之又少.我真誠的獻上以供同根生的苦逼程式設計師.

實現原理:自定義ImageView對此控制元件進行相應的layout(動態佈局).

這裡你要明白幾個方法執行的流程: 首先ImageView是繼承自View的子類.

onLayout方法:是一個回撥方法.該方法會在在View中的layout方法中執行,在執行layout方法前面會首先執行setFrame方法.

setFrame方法:判斷我們的View是否發生變化,如果發生變化,那麼將最新的l,t,r,b傳遞給View,然後重新整理進行動態更新UI. 並且返回ture.沒有變化返回false.

在介紹自定義控制元件之前,我們先要明白我們要獲取哪些資料:螢幕的寬度,螢幕的高度.(這裡其實你也可以對LinerLayout進行ViewTreeObserver監聽獲取其寬高度.),原始圖片本身的寬度及高度.以及我們縮放的最大最小值.

首先我們要重寫setImageBitmap方法.作用:獲取圖片的寬高,求出縮放極限值.

  1. /*** 
  2.      * 設定顯示圖片 
  3.      */
  4.     @Override
  5.     publicvoid setImageBitmap(Bitmap bm) {  
  6.         super.setImageBitmap(bm);  
  7.         /** 獲取圖片寬高 **/
  8.         bitmap_W = bm.getWidth();  
  9.         bitmap_H = bm.getHeight();  
  10.         MAX_W = bitmap_W * 3;  
  11.         MAX_H = bitmap_H * 3;  
  12.         MIN_W = bitmap_W / 2;  
  13.         MIN_H = bitmap_H / 2;  
  14.     }  

接著我們在onLayout方法中我們獲取最初的l,t,r,b.

  1. @Override
  2.     protectedvoid onLayout(boolean changed, int left, int top, int right,  
  3.             int bottom) {  
  4.         super.onLayout(changed, left, top, right, bottom);  
  5.         if (start_Top == -1) {  
  6.             start_Top = top;  
  7.             start_Left = left;  
  8.             start_Bottom = bottom;  
  9.             start_Right = right;  
  10.         }  
  11.     }  

下面我們說下重點Touch方法.其實原來大家都明白,要說難的話估計就是邏輯實現了.

說之前大家要明白單點與多點的區別:

單手指操作:ACTION_DOWN---ACTION_MOVE----ACTION_UP

多手指操作:ACTION_DOWN---ACTION_POINTER_DOWN---ACTION_MOVE--ACTION_POINTER_UP---ACTION_UP.

上面只是簡單說下流程,詳細請大家自行研究,這裡只是講解如果運用.

  1. /*** 
  2.      * touch 事件 
  3.      */
  4.     @Override
  5.     publicboolean onTouchEvent(MotionEvent event) {  
  6.         /** 處理單點、多點觸控 **/
  7.         switch (event.getAction() & MotionEvent.ACTION_MASK) {  
  8.         case MotionEvent.ACTION_DOWN:  
  9.             onTouchDown(event);  
  10.             break;  
  11.         // 多點觸控
  12.         case MotionEvent.ACTION_POINTER_DOWN:  
  13.             onPointerDown(event);  
  14.             break;  
  15.         case MotionEvent.ACTION_MOVE:  
  16.             onTouchMove(event);  
  17.             break;  
  18.         case MotionEvent.ACTION_UP:  
  19.             mode = MODE.NONE;  
  20.             break;  
  21.         // 多點鬆開
  22.         case MotionEvent.ACTION_POINTER_UP:  
  23.             mode = MODE.NONE;  
  24.             /** 執行縮放還原 **/
  25.             if (isScaleAnim) {  
  26.                 doScaleAnim();  
  27.             }  
  28.             break;  
  29.         }  
  30.         returntrue;  
  31.     }  
這裡的實現我都分開寫了,利於大家的觀看,在這裡我順便說一下自定義控制元件返回值:如果對於沒有孩子的控制元件,如果要對Touch處理最好return true.這樣也是遊戲開發中經常用的,如果該控制元件有孩子的話,可不要這麼弄,不然孩子會監聽不到Touch事件.

下面我們一個一個方法的看:

onTouchDown:獲取手指點選時候的起始座標.

  1. /** 按下 **/
  2.     void onTouchDown(MotionEvent event) {  
  3.         mode = MODE.DRAG;  
  4.         current_x = (int) event.getRawX();  
  5.         current_y = (int) event.getRawY();  
  6.         start_x = (int) event.getX();  
  7.         start_y = current_y - this.getTop();  
  8.     }  
這裡大家也要明白 event.getRawX()和event.getX(),不過我相信大家都明白的,我前面那篇ListView拖拽也提到過.一個相對螢幕,一個相對父控制元件.

onPointerDown:兩手指之間的距離.

  1. /** 兩個手指 只能放大縮小 **/
  2.     void onPointerDown(MotionEvent event) {  
  3.         if (event.getPointerCount() == 2) {  
  4.             mode = MODE.ZOOM;  
  5.             beforeLenght = getDistance(event);// 獲取兩點的距離
  6.         }  
  7.     }  
onTouchMove:移動的處理.
  1. /** 移動的處理 **/
  2. void onTouchMove(MotionEvent event) {  
  3.     int left = 0, top = 0, right = 0, bottom = 0;  
  4.     /** 處理拖動 **/
  5.     if (mode == MODE.DRAG) {  
  6.         /** 在這裡要進行判斷處理,防止在drag時候越界 **/
  7.         /** 獲取相應的l,t,r ,b **/
  8.         left = current_x - start_x;  
  9.         right = current_x + this.getWidth() - start_x;  
  10.         top = current_y - start_y;  
  11.         bottom = current_y - start_y + this.getHeight();  
  12.         /** 水平進行判斷 **/
  13.         if (isControl_H) {  
  14.             if (left >= 0) {  
  15.                 left = 0;  
  16.                 right = this.getWidth();  
  17.             }  
  18.             if (right <= screen_W) {  
  19.                 left = screen_W - this.getWidth();  
  20.                 right = screen_W;  
  21.             }  
  22.         } else {  
  23.             left = this.getLeft();  
  24.             right = this.getRight();  
  25.         }  
  26.         /** 垂直判斷 **/
  27.         if (isControl_V) {  
  28.             if (top >= 0) {  
  29.                 top = 0;  
  30.                 bottom = this.getHeight();  

相關推薦

android 定義ImageView實現圖片手勢滑動 觸控放大縮小效果

                轉自:http://blog.csdn.net/jj120522/article/details/8467810首先呢,還是一貫作風,我們先來看看眾多應用中的示例:(這種效果是很常見的,可以說應用的必須品.)                           搜狐客戶端  

android 定義ImageView實現圖片手勢滑動觸控放大縮小效果

首先呢,還是一貫作風,我們先來看看眾多應用中的示例:(這種效果是很常見的,可以說應用的必須品.)                             搜狐客戶端                                    百度新聞客戶端          

android定義imageview實現圓角圖片

自定義圖片的屬性,對圖片進行圓角切割 實現效果圖: (1)在activity_main.xml檔案佈局,非常簡單 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:androi

Android定義view實現圖片選色器

https://www.jb51.net/article/141336.htm 這篇文章主要為大家詳細介紹了Android自定義view實現圖片選色器,具有一定的參考價值,感興趣的小夥伴們可以參考一下 簡介 本文介紹該自定義view的使用及實現的方法,主要實現以下幾個功能: - 選取

Android定義View實現圖片顯示,並實現縮放、拖拽、切換功能

這裡貼三個檔案的原始碼,第一個是main.java package com.example.test; import java.util.ArrayList; import java.util.List; import com.example.test.MyXZ; i

定義ImageView實現圖片圓角效果

lamp onmeasure null wid resources mar ctf ppc fig 效果圖如下 代碼 package activity.yyzy.com.schoolsecondhand.myview; import android.content.Co

定義ImageView: 實現自由縮放 ,自由移動縮放後的圖片 .雙擊放大縮小圖片 相容ViewPager

直接擼程式碼, 複製就能用 package com.zhf.baselibrary.view; import android.annotation.SuppressLint; import android.content.Context; import android.graphi

android 定義ScrollView實現背景圖片伸縮(阻尼效果)

android 自定義ScrollView實現強調內容背景圖片伸縮(仿多米,qq空間背景的重新整理) bug修改:只需將自定義PersonalScrollView的真假判斷修改即可,修改後的程式碼片段如下: case MotionEven

android定義Gallery實現手動和自動迴圈滾動切換圖片

實現類似騰訊視訊頂欄的圖片切換,網上找了下寫的都不全,現在總結下我實現過程中遇到的問題: 第一個問題:Gallery手動滑動翻頁 參照網上的方法實現如下:   自定義MyGalleyry繼承自Gallery  重寫onFling方法 private boolean isScrollingLeft(Motio

Android定義imageview可對圖片進行縮放和拖動

package com.msstudent.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import andro

Android定義 view之圖片裁剪從設計到實現

android圖片剪下是常用的功能,因為部落格開發的是SDK不涉及到activity,所以就需要自定義裁剪功能,參閱了網上的大部分資料後,在github上一個封裝好的裁剪庫cropper,正好符合要求,本著拿來主義的思想,直接把原始碼clone嵌入到專案裡,然後

Android -- 定義view實現keep歡迎頁倒計時效果

super onfinish -m use new getc awt ttr alt 1,最近打開keep的app的時候,發現它的歡迎頁面的倒計時效果還不錯,所以打算自己來寫寫,然後就有了這篇文章。 2,還是老規矩,先看一下我們今天實現的效果   相較於我們常見的倒計時

Android定義View——實現水波紋效果類似剩余流量球

string 三個點 pre ber block span 初始化 move 理解 最近突然手癢就想搞個貝塞爾曲線做個水波紋效果玩玩,終於功夫不負有心人最後實現了想要的效果,一起來看下吧: 效果圖鎮樓 一:先一步一步來分解一下實現的過程 需要繪制一個正弦曲線(sin

Android 定義控件——圖片剪裁

ets nis anti none span out pro int() mat 如圖: 思路:在一個自定義View上繪制一張圖片(參照前面提到的另一篇文章),在該自定義View上繪制一個自定義的FloatDrawable,也就是圖中的浮層。繪制圖片和FloatDra

Android定義processor實現bindView功能

lis dds 定義 java代碼 cli 註冊 文章 type() mage 一、簡介 在現階段的Android開發中,註解越來越流行起來,比如ButterKnife,Retrofit,Dragger,EventBus等等都選擇使用註解來配置。按照處理時期,註解又分為兩

Android 定義相機 Camera 圖片方向問題

相機預覽方向問題 對於相機的預覽方向我們可以通過如下API進行設定 camera.setDisplayOrientation(0);但是,該API影響的是相機的預覽方向,對於照片的儲存方向並沒有什麼影響,最終照片儲存的方向還是由Camera的影象Sensor決定的。 照片儲

Android :定義view實現簡易的轉盤

直接先上效果圖 xml裡面的程式碼 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

Android 定義View實現拖拽效果

騰訊QQ有那種紅點拖動效果,今天就來實現一個簡單的自定義View拖動效果,再回到原處,並非完全仿QQ紅點拖動 先來看一下效果圖 簡單說一下實現步驟 1.建立一個類繼承View 2.繪製出一個

Android定義View實現類似車來了軌跡圖

總體分析下:水平方向recyclewview,item包含定位點,站臺位置和站臺名稱。 下面看實現: 1.繼承framelayout,實現構造方法: public class BusStopPlateView extends FrameLayout { ... public

Android 定義View實現圓形環繞效果

之前專案中需要實現一個四周環繞中心圓形頭像的效果,感覺還是自定義比較方便,於是就自己封裝了一個控制元件去實現。先貼張圖顯示最終效果。 首先自定義一個View繼承自LinearLayout,通過動態新增childView的方式將子控制元件新增到View中。思路是先新增中間圓形頭像