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

推荐阅读:

查看原文 >>
相关文章