android imageview 多點觸碰(MultiTouch)實現圖片拖拽移動縮放

2012-3-19 09:39|發布者: benben|查看: 344|評論: 0

摘要: 剛用android手機 發現手機自帶的圖片瀏覽器挺酷 可以用手指移動 縮放 還有動畫效果Intent intent = new Intent(Intent.ACTION_VIEW);intent.setDataAndType(Uri.fromFile(recentFile), "image/*"); startAct ...

剛用android手機 發現手機自帶的圖片瀏覽器挺酷 可以用手指移動 縮放 還有動畫效果

Intent intent = new Intent(Intent.ACTION_VIEW);intent.setDataAndType(Uri.fromFile(recentFile), "image/*"); startActivity(intent);

就可以調用系統的圖片瀏覽器查看手機上的圖片了

於是想仿照著寫一個

到網上看了不少資料 大概分為兩種實現方式

http://download.csdn.net/source/3318880 ->源碼

一種是利用Matrix的postTranslate和postScale方法分別進行移動和縮放

這種方式實質是對ImageView中的drawable進行縮放和移動

imageview組件本身並沒有移動和縮放 這種方法實現起來比較簡單但是不知道如何獲得經過移動後的drawable的坐標和大小 比較鬱悶 因為調用imageview的各種方法拿到的都是其本身的大小和坐標

而另一種是直接對imageview進行操作,直接移動和改變組件本身的大小從而實現移動和縮放

核心類 繼承->ImageView 並加入了一些動畫效果

import android.content.Context;import android.util.FloatMath;import android.view.MotionEvent;import android.view.animation.TranslateAnimation;import android.widget.ImageView;/*** 繼承ImageView 實現了多點觸碰的拖動和縮放* @author Administrator**/publicclassTouchViewextendsImageView{staticfinalint NONE =0;staticfinalint DRAG =1;//拖動中staticfinalint ZOOM =2;//縮放中staticfinalint BIGGER =3;//放大ingstaticfinalint SMALLER =4;//縮小ingprivateint mode = NONE;//當前的事件 privatefloat beforeLenght;//兩觸點距離privatefloat afterLenght;//兩觸點距離privatefloat scale =0.04f;//縮放的比例 X Y方向都是這個值 越大縮放的越快privateint screenW;privateint screenH;/*處理拖動 變數 */privateint start_x;privateint start_y;privateint stop_x ;privateint stop_y ;privateTranslateAnimation trans;//處理超出邊界的動畫publicTouchView(Context context,int w,int h){super(context);this.setPadding(0,0,0,0);screenW = w;screenH = h;}/*** 就算兩點間的距離*/privatefloat spacing(MotionEventevent){float x =event.getX(0)-event.getX(1);float y =event.getY(0)-event.getY(1);returnFloatMath.sqrt(x * x + y * y);}/*** 處理觸碰..*/@Overridepublicboolean onTouchEvent(MotionEventevent){switch(event.getAction()&MotionEvent.ACTION_MASK){caseMotionEvent.ACTION_DOWN:mode = DRAG;stop_x =(int)event.getRawX();stop_y =(int)event.getRawY();start_x =(int)event.getX();start_y = stop_y -this.getTop();if(event.getPointerCount()==2)beforeLenght = spacing(event);break;caseMotionEvent.ACTION_POINTER_DOWN:if(spacing(event)>10f){mode = ZOOM;beforeLenght = spacing(event);}break;caseMotionEvent.ACTION_UP:/*判斷是否超出範圍 並處理*/int disX =0;int disY =0;if(getHeight()<=screenH ||this.getTop()<0){if(this.getTop()<0){int dis = getTop();this.layout(this.getLeft(),0,this.getRight(),0+this.getHeight());disY = dis - getTop();}elseif(this.getBottom()>screenH){disY = getHeight()- screenH+getTop();this.layout(this.getLeft(), screenH-getHeight(),this.getRight(), screenH);}}if(getWidth()<=screenW){if(this.getLeft()<0){disX = getLeft();this.layout(0,this.getTop(),0+getWidth(),this.getBottom());}elseif(this.getRight()>screenW){disX = getWidth()-screenW+getLeft();this.layout(screenW-getWidth(),this.getTop(), screenW,this.getBottom());}}if(disX!=0|| disY!=0){trans =newTranslateAnimation(disX,0, disY,0);trans.setDuration(500);this.startAnimation(trans);}mode = NONE;break;caseMotionEvent.ACTION_POINTER_UP:mode = NONE;break;caseMotionEvent.ACTION_MOVE:/*處理拖動*/if(mode == DRAG){if(Math.abs(stop_x-start_x-getLeft())<88&&Math.abs(stop_y - start_y-getTop())<85){this.setPosition(stop_x - start_x, stop_y - start_y, stop_x +this.getWidth()- start_x, stop_y - start_y +this.getHeight());stop_x =(int)event.getRawX();stop_y =(int)event.getRawY();}}/*處理縮放*/elseif(mode == ZOOM){if(spacing(event)>10f){afterLenght = spacing(event);float gapLenght = afterLenght - beforeLenght;if(gapLenght ==0){break;}elseif(Math.abs(gapLenght)>5f){if(gapLenght>0){this.setScale(scale,BIGGER);}else{this.setScale(scale,SMALLER);}beforeLenght = afterLenght;}}}break;}returntrue;}/*** 實現處理縮放*/privatevoid setScale(float temp,int flag){if(flag==BIGGER){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()));}elseif(flag==SMALLER){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()));}}/*** 實現處理拖動*/privatevoid setPosition(int left,int top,int right,int bottom){this.layout(left,top,right,bottom);}}

裝載類 一個layout

import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.view.View;import android.widget.AbsoluteLayout;import android.widget.ImageView.ScaleType;/*** 一個絕對布局 * @author Administrator**/@SuppressWarnings("deprecation")publicclassViewScrollextendsAbsoluteLayout{privateint screenW;//可用的屏幕寬privateint screenH;//可用的屏幕高 總高度-上面組件的總高度privateint imgW;//圖片原始寬privateint imgH;//圖片原始高privateTouchView tv;publicViewScroll(Context context,int resId,View topView){super(context);screenW =((Activity)context).getWindowManager().getDefaultDisplay().getWidth();screenH =((Activity)context).getWindowManager().getDefaultDisplay().getHeight()-(topView==null?190:topView.getBottom()+50);tv =newTouchView(context,screenW,screenH);tv.setImageResource(resId);Bitmap img =BitmapFactory.decodeResource(context.getResources(), resId);imgW = img.getWidth();imgH = img.getHeight();int layout_w = imgW>screenW?screenW:imgW;//實際顯示的寬int layout_h = imgH>screenH?screenH:imgH;//實際顯示的高if(layout_w==screenW||layout_h==screenH)tv.setScaleType(ScaleType.FIT_XY);tv.setLayoutParams(newAbsoluteLayout.LayoutParams(layout_w,layout_h , layout_w==screenW?0:(screenW-layout_w)/2, layout_h==screenH?0:(screenH-layout_h)/2));this.addView(tv);}}

Activity:

import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.Gallery;import android.widget.LinearLayout;import android.widget.AdapterView.OnItemClickListener;/*** activity* @author Administrator**/publicclassGalleryMainextendsActivityimplementsOnItemClickListener{privateViewScroll detail;privateImageAdapter ia;privateLinearLayout ll;privateLinearLayout.LayoutParams parm;privateGallery g;@Overrideprotectedvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);g =(Gallery) findViewById(R.id.myggg);ll =(LinearLayout) findViewById(R.id.twill);parm =newLinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);ia =newImageAdapter(this);detail =newViewScroll(GalleryMain.this, ia.imgIds[0],g);ll.addView(detail,parm);g.setAdapter(ia);g.setOnItemClickListener(this);}@Overridepublicvoid onItemClick(AdapterView<?> arg0,View arg1,int arg2,long arg3){ll.removeView(detail);detail =newViewScroll(GalleryMain.this, ia.imgIds[arg2],g);ll.addView(detail,parm);}}

配合Gallery的適配器類:

import android.content.Context;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Gallery;import android.widget.ImageView;import android.widget.ImageView.ScaleType;/*** Gallery的適配器類* @author Administrator**/publicclassImageAdapterextendsBaseAdapter{/*圖片素材*/publicint[] imgIds ={R.drawable.jpg,R.drawable.pic};privateContext context;publicImageAdapter(Context context){this.context = context;}@Overridepublicint getCount(){return imgIds.length;}@OverridepublicObject getItem(int position){returnnull;}@Overridepubliclong getItemId(int position){return0;}@OverridepublicView getView(int position,View convertView,ViewGroup parent){ImageView img =newImageViewImp(context);img.setImageResource(imgIds[position]);img.setScaleType(ScaleType.CENTER);img.setLayoutParams(newGallery.LayoutParams(155,150));return img;}}

gallery中image的實現類:

import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.drawable.BitmapDrawable;import android.view.MotionEvent;import android.widget.ImageView;/*** ImageAdapter中ImageView的實現類* @author Administrator**/publicclassImageViewImpextendsImageView{privateint alpha =250;privateboolean pressed =false;publicImageViewImp(Context context){super(context);}Matrix m;publicvoid show(){newThread(){publicvoid run(){int time =2000;try{pressed =true;while(time>0){Thread.sleep(200);time -=200;alpha-=25;postInvalidate();}pressed =false;}catch(Exception e){e.printStackTrace();}};}.start();}@Overridepublicboolean onTouchEvent(MotionEventevent){if(event.getAction()==MotionEvent.ACTION_DOWN)show();returnfalse;}@Overrideprotectedvoid onDraw(Canvas canvas){Paint p =newPaint();p.setColor(Color.WHITE);p.setStyle(Paint.Style.STROKE);p.setStrokeWidth(10);BitmapDrawable bd =(BitmapDrawable) getDrawable();if(bd!=null){canvas.drawBitmap(imageScale(bd.getBitmap(),107,113),21,18, p);}canvas.drawBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.kua),0,0, p);if(isPressed()){canvas.drawRect(5,5,140,140,p);}if(pressed){p.setAlpha(alpha);canvas.drawRect(5,5,140,140,p);}}publicstaticBitmap imageScale(Bitmap bitmap,int dst_w,int dst_h){int src_w = bitmap.getWidth();int src_h

推薦閱讀:

查看原文 >>
相关文章