天天看點

Android學習之多點觸摸并不神秘

最近研究了一下多點觸摸,寫了個利用多點觸摸來控制圖檔大小和單點觸摸控制圖檔移動的程式,和大家分享分享。

Android中監聽觸摸事件是onTouchEvent方法,它的參數為MotionEvent,下面列舉MotionEvent的一些常用的方法:

getPointerCount() 獲得觸屏的點數。

getX() 獲得觸屏的X坐标值

getY() 獲得觸屏的Y坐标值

getAction() 獲得觸屏的動作

ACTION_DOWN:按下的動作開始,比如用手指按螢幕。

ACTION_UP:按下的動作完成,比如手指停止按螢幕,離開螢幕。

ACTION_MOVE:在動作開始和完成之間的移動,比如手指在螢幕上滑動。

還介紹下程式中用到的ImageView,ImageView.setFrame()的四個參數指的是left,top,right,bottom如圖:

left和top指的就是ImageView左上角的坐标x和y,right,bottom指的就是ImageView的右下角的坐标x和y了。

接下來看程式,程式中有詳細的介紹:

[java] view plaincopy

package com.practice.imageviewpic;  

import android.app.Activity;  

import android.content.Context;  

import android.graphics.*;  

import android.graphics.drawable.BitmapDrawable;  

import android.os.Bundle;  

import android.view.MotionEvent;  

import android.widget.ImageView;  

import android.widget.ImageView.ScaleType;  

public class ImageViewPic extends Activity {  

    /* 

     * 利用多點觸控來控制ImageView中圖像的放大與縮小 

     * 手指控制圖檔移動 

     */  

    private MyImageView imageView;  

    private Bitmap bitmap;  

    //兩點觸屏後之間的長度  

    private float beforeLenght;  

    private float afterLenght;  

    //單點移動的前後坐标值  

    private float afterX,afterY;  

    private float beforeX,beforeY;  

    /** Called when the activity is first created. */  

    @Override  

    public void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        findView();  

        setContentView(imageView);  

        config();  

    }  

    private void findView() {  

        imageView = new MyImageView(this);  

        //獲得圖檔  

        bitmap = ((BitmapDrawable)getResources().getDrawable(R.drawable.xing)).getBitmap();  

    private void config() {  

        //設定imageView的顯示圖檔  

        imageView.setImageBitmap(bitmap);  

        //設定圖檔填充ImageView  

        imageView.setScaleType(ScaleType.FIT_XY);  

    //建立一個自己的ImageView類  

    class MyImageView extends ImageView {  

        private float scale = 0.1f;  

        public MyImageView(Context context) {  

            super(context);  

        }  

        //用來設定ImageView的位置  

        private void setLocation(int x,int y) {  

            this.setFrame(this.getLeft()+x, this.getTop()+y, this.getRight()+x, this.getBottom()+y);  

        /* 

         * 用來放大縮小ImageView 

         * 因為圖檔是填充ImageView的,是以也就有放大縮小圖檔的效果 

         * flag為0是放大圖檔,為1是小于圖檔 

         */  

        private void setScale(float temp,int flag) {  

            if(flag==0) {  

                this.setFrame(this.getLeft()-(int)(temp*this.getWidth()),   

                              this.getTop()-(int)(temp*this.getHeight()),   

                              this.getRight()+(int)(temp*this.getWidth()),   

                              this.getBottom()+(int)(temp*this.getHeight()));     

            }else {  

                this.setFrame(this.getLeft()+(int)(temp*this.getWidth()),   

                              this.getTop()+(int)(temp*this.getHeight()),   

                              this.getRight()-(int)(temp*this.getWidth()),   

                              this.getBottom()-(int)(temp*this.getHeight()));  

            }  

        //繪制邊框        

         @Override  

          protected void onDraw(Canvas canvas) {  

              super.onDraw(canvas);      

              Rect rec=canvas.getClipBounds();  

              rec.bottom--;  

              rec.right--;  

              Paint paint=new Paint();  

              paint.setColor(Color.RED);  

              paint.setStyle(Paint.Style.STROKE);  

              canvas.drawRect(rec, paint);  

          }  

        /* 讓圖檔跟随手指觸屏的位置移動 

         * beforeX、Y是用來儲存前一位置的坐标 

         * afterX、Y是用來儲存目前位置的坐标 

         * 它們的內插補點就是ImageView各坐标的增加或減少值 

        public void moveWithFinger(MotionEvent event) {  

            switch(event.getAction()) {  

            case MotionEvent.ACTION_DOWN:  

                beforeX = event.getX();  

                beforeY = event.getY();  

                break;  

            case MotionEvent.ACTION_MOVE:  

                afterX = event.getX();  

                afterY = event.getY();  

                this.setLocation((int)(afterX-beforeX),(int)(afterY-beforeY));  

                beforeX = afterX;  

                beforeY = afterY;  

            case MotionEvent.ACTION_UP:  

         * 通過多點觸屏放大或縮小圖像 

         * beforeLenght用來儲存前一時間兩點之間的距離 

         * afterLenght用來儲存目前時間兩點之間的距離 

        public void scaleWithFinger(MotionEvent event) {  

            float moveX = event.getX(1) - event.getX(0);  

            float moveY = event.getY(1) - event.getY(0);  

                beforeLenght = (float) Math.sqrt( (moveX*moveX) + (moveY*moveY) );  

                //得到兩個點之間的長度  

                afterLenght = (float) Math.sqrt( (moveX*moveX) + (moveY*moveY) );  

                float gapLenght = afterLenght - beforeLenght;  

                if(gapLenght == 0) {  

                    break;  

                }  

                //如果目前時間兩點距離大于前一時間兩點距離,則傳0,否則傳1  

                if(gapLenght>0) {  

                    this.setScale(scale,0);  

                }else {  

                    this.setScale(scale,1);  

                beforeLenght = afterLenght;  

   //這裡來監聽螢幕觸控時間  

   @Override  

    public boolean onTouchEvent(MotionEvent event) {  

       /* 

        * 判定使用者是否觸摸到了圖檔 

        * 如果是單點觸摸則調用控制圖檔移動的方法 

        * 如果是2點觸控則調用控制圖檔大小的方法 

        */  

        if(event.getY() > imageView.getTop() && event.getY() < imageView.getBottom()  

                && event.getX() > imageView.getLeft() && event.getX() < imageView.getRight()) {  

            if(event.getPointerCount() == 2) {  

                imageView.scaleWithFinger(event);  

            }else if(event.getPointerCount() == 1) {  

                imageView.moveWithFinger(event);  

            }             

        return true;  

    }         

}  

源程式的下載下傳位址為