android Matrix圖片隨意的放大縮小,拖動,翻頁 – Android移動開發技術文章_手機開發 Android移動開發教學課程

不知道大傢有沒有買小米,小米手機自帶瞭一個圖片查看器,他能對圖片進行隨意的瀏覽,擴大,縮小,以及翻頁,使用效果感覺非常的不錯
今天認著有時間,也就模仿他的功能寫瞭一下,遇到不少的挫折,看不瞭不少的資料,希望今天的功夫沒有白做,也希望對大傢有幫助
在怎麼說功能實現瞭,並結合自己現在所做的項目,進行瞭些許的改動,感覺更容易普及的使用,因為我們很多時候要從網上下載圖片
然後對圖片進行瀏覽什麼的。
 
 在做之前,說下思路:
 目標: 實現 拖,拉,拽,擴大,縮小,以及翻屏
主要分兩個大的方向:
    1  拖,拉,拽,擴大,縮小 在本屏幕操作
    2  翻屏是的額外的做,也並不是隨意的就能翻屏,必須滿足條件
   但是當我們實現OnTouchListener 時候,他提供的隻有 ACTION_DOWN, ACTION_MOVE, ACTION_UP 等操作
所以我們必須分情況,並且是三種情況:
   第一種: none  可能用戶什麼也不做
   第二種: DRAG  滑屏
   第三種: ZOOM 擴大縮小
 同時本程序考慮到有的android山寨手機可能還不支持多點觸摸,所以同時加入瞭兩個button ,不支持的多點觸摸的也能對圖片進行動態的擴大或者縮小
當然主要用的知識點就是Matrix 矩陣的一些常用方法,擴大,縮小,平移,偏移,剩下的都是一點皮毛的算法邏輯瞭,代碼自己看啊
先上個圖:
 
下面是代碼:

/*
 * @project testbmplarge
 * @package com.bmp.large
 * @file testactivity.java
 * @version  1.0
 * @author  yourname
 * @time  2012-1-6 ����10:58:20
 * CopyRight:������������Ϣ�������޹�˾ 2012-1-6
 */ 
package com.bmp.large; 
 
import android.app.Activity; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Matrix; 
import android.graphics.PointF; 
import android.os.Bundle; 
import android.util.DisplayMetrics; 
import android.util.FloatMath; 
import android.util.Log; 
import android.view.GestureDetector; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.GestureDetector.OnGestureListener; 
import android.view.View.OnClickListener; 
import android.view.View.OnTouchListener; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.Toast; 
 
public class testactivity extends Activity implements OnTouchListener,OnClickListener{ 
    /*
     *
     * Class Descripton goes here.
     *
     * @class testactivity
     * @version  1.0
     * @author  yourname
     * @time  2012-1-6 ����10:58:20
     */ 
    private Button big,small; 
    private  Bitmap newbitmap; 
    private GestureDetector mGestureDetector; 
    Matrix matrix = new Matrix(); 
    Matrix savedMatrix = new Matrix(); 
    ImageView bmp; 
    PointF first = new PointF(); 
    PointF start = new PointF(); 
    PointF mid = new PointF();; 
    private float oldDist; 
    static final int NONE = 0; 
    static final int DRAG = 1; 
    static final int ZOOM = 2; 
    int mode = NONE; 
    private long beginTime,endTime; 
     @Override 
     public void onCreate(Bundle savedInstanceState)    { 
      super.onCreate(savedInstanceState); 
      /*display.xml Layout */ 
      setContentView(R.layout.main); 
     
      big = (Button)this.findViewById(R.id.big); 
      small = (Button)this.findViewById(R.id.small); 
     
      big.setOnClickListener(this); 
      small.setOnClickListener(this); 
      
      //獲取手機屏幕的寬和高 
      DisplayMetrics dm = new DisplayMetrics();    
      getWindowManager().getDefaultDisplay().getMetrics(dm);   
     
      int width = dm.widthPixels; 
      int height = dm.heightPixels; 
       
       
      // 獲取圖片本身的寬 和高 
      Bitmap mybitmap=BitmapFactory.decodeResource(getResources(), R.drawable.default_head); 
      System.out.println("old==="+mybitmap.getWidth()); 
       
      int widOrg=mybitmap.getWidth(); 
      int heightOrg=mybitmap.getHeight(); 
       
      // 寬 高 比列 
      float scaleWid = (float)width/widOrg; 
      float scaleHeight = (float)height/heightOrg; 
      float scale; 
       
      bmp = (ImageView)this.findViewById(R.id.bmp); 
       
      // 如果寬的 比列大於搞的比列 則用高的比列 否則用寬的 
       
       
      if(scaleWid>scaleHeight) 
      { 
          scale = scaleHeight; 
      } 
      else 
          scale = scaleWid; 
       
 //     matrix=new Matrix(); 
      bmp.setImageBitmap(mybitmap); 
       
      matrix.postScale(scale,scale); 
      
      bmp.setImageMatrix(matrix); 
       
      bmp.setOnTouchListener(this); 
      
      bmp.setLongClickable(true); 
     
      savedMatrix.set(matrix); 
     } 
      @Override 
    public boolean onTouch(View v, MotionEvent event) { 
        // TODO Auto-generated method stub 
//        mGestureDetector.onTouchEvent(event); 
          System.out.println("action==="+event.getAction()); 
          switch(event.getAction()& MotionEvent.ACTION_MASK) 
          { 
            case MotionEvent.ACTION_DOWN: 
                 
                beginTime = System.currentTimeMillis(); 
                 
                mode = DRAG; 
                System.out.println("down"); 
                first.set(event.getX(), event.getY()); 
                start.set(event.getX(), event.getY()); 
                break; 
            case MotionEvent.ACTION_UP: 
                 
                endTime = System.currentTimeMillis(); 
                 
                System.out.println("endTime=="+(endTime – beginTime)); 
                float x = event.getX(0) – first.x; 
                float y = event.getY(0) – first.y; 
                // 多長的距離 
                float move = FloatMath.sqrt(x * x + y * y); 
                 
                System.out.println("move=="+(move)); 
                 
                // 計算時間和移動的距離  來判斷你想要的操作,經過測試90%情況能滿足 
                if(endTime – beginTime<500&&move>20) 
                { 
                    //這裡就是做你上一頁下一頁的事情瞭。 
                    Toast.makeText(this, "—-do something—–", 1000).show(); 
                } 
                break; 
            case MotionEvent.ACTION_MOVE: 
                 
                System.out.println("move"); 
                if(mode == DRAG) 
                { 
                    matrix.postTranslate(event.getX()-start.x, event.getY()-start.y); 
                    start.set(event.getX(), event.getY()); 
                } 
                else 
                { 
                    float newDist = spacing(event); 
                    if (newDist > 10f) { 
//                  matrix.set(savedMatrix); 
                    float scale = newDist / oldDist; 
                    System.out.println("scale=="+scale); 
                    matrix.postScale(scale, scale, mid.x, mid.y); 
                    } 
                    oldDist = newDist; 
                } 
                break; 
            case MotionEvent.ACTION_POINTER_DOWN: 
                oldDist = spacing(event); 
                if (oldDist > 10f) { 
                    midPoint(mid, event); 
                    mode = ZOOM; 
                    } 
                System.out.println("ACTION_POINTER_DOWN"); 
                break; 
            case MotionEvent.ACTION_POINTER_UP: 
                System.out.println("ACTION_POINTER_UP"); 
                break; 
          } 
          bmp.setImageMatrix(matrix); 
        return false; 
    } 
 
     
 
    @Override 
    public void onClick(View v) { 
        // TODO Auto-generated method stub 
        if(v==small) 
        { 
            matrix.postScale(0.5f,0.5f,0,0); 
//          matrix.setScale(0.5f, 0.5f); 
            bmp.setImageMatrix(matrix); 
        } 
        else 
        { 
            matrix.postScale(2f,2f); 
//          matrix.setScale(2f,2f); 
            bmp.setImageMatrix(matrix); 
        } 
    } 
    /**
     * 計算拖動的距離
     * @param event
     * @return
     */ 
    private float spacing(MotionEvent event) { 
        float x = event.getX(0) – event.getX(1); 
        float y = event.getY(0) – event.getY(1); 
        return FloatMath.sqrt(x * x + y * y); 
    } 
    /**
     * 計算兩點的之間的中間點
     * @param point
     * @param event
     */ 
     
    private void midPoint(PointF point, MotionEvent event) { 
        float x = event.getX(0) + event.getX(1); 
        float y = event.getY(0) + event.getY(1); 
        point.set(x / 2, y / 2); 
    } 

摘自 android小益的專欄

發佈留言