android imageview 多点触碰(MultiTouch)实现图片拖拽移动缩放

刚用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 * */ public class TouchView extends ImageView { static final int NONE = 0; static final int DRAG = 1; //拖动中 static final int ZOOM = 2; //缩放中 static final int BIGGER = 3; //放大ing static final int SMALLER = 4; //缩小ing private int mode = NONE; //当前的事件 private float beforeLenght; //两触点距离 private float afterLenght; //两触点距离 private float scale = 0.04f; //缩放的比例 X Y方向都是这个值 越大缩放的越快 private int screenW; private int screenH; /*处理拖动 变量 */ private int start_x; private int start_y; private int stop_x ; private int stop_y ; private TranslateAnimation trans; //处理超出边界的动画 public TouchView(Context context,int w,int h) { super(context); this.setPadding(0, 0, 0, 0); screenW = w; screenH = h; } /** * 就算两点间的距离 */ 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); } /** * 处理触碰.. */ @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.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; case MotionEvent.ACTION_POINTER_DOWN: if (spacing(event) > 10f) { mode = ZOOM; beforeLenght = spacing(event); } break; case MotionEvent.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(); } else if(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()); } else if(this.getRight()>screenW) { disX = getWidth()-screenW+getLeft(); this.layout(screenW-getWidth(), this.getTop(), screenW, this.getBottom()); } } if(disX!=0 || disY!=0) { trans = new TranslateAnimation(disX, 0, disY, 0); trans.setDuration(500); this.startAnimation(trans); } mode = NONE; break; case MotionEvent.ACTION_POINTER_UP: mode = NONE; break; case MotionEvent.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(); } } /*处理缩放*/ else if (mode == ZOOM) { if(spacing(event)>10f) { afterLenght = spacing(event); float gapLenght = afterLenght - beforeLenght; if(gapLenght == 0) { break; } else if(Math.abs(gapLenght)>5f) { if(gapLenght>0) { this.setScale(scale,BIGGER); }else { this.setScale(scale,SMALLER); } beforeLenght = afterLenght; } } } break; } return true; } /** * 实现处理缩放 */ private void 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())); }else if(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())); } } /** * 实现处理拖动 */ private void 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") public class ViewScroll extends AbsoluteLayout { private int screenW; //可用的屏幕宽 private int screenH; //可用的屏幕高 总高度-上面组件的总高度 private int imgW; //图片原始宽 private int imgH; //图片原始高 private TouchView tv; public ViewScroll(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 = new TouchView(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(new AbsoluteLayout.LayoutParams(layout_w,layout_h , layout_w==screenW?0:(screenW-layout_w)/2, layout_h==screenH?0:(screenH-layout_h)/2)); this.addView(tv); } }


Activit

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 * */ public class GalleryMain extends Activity implements OnItemClickListener { private ViewScroll detail; private ImageAdapter ia; private LinearLayout ll; private LinearLayout.LayoutParams parm; private Gallery g; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); g = (Gallery) findViewById(R.id.myggg); ll = (LinearLayout) findViewById(R.id.twill); parm = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); ia = new ImageAdapter(this); detail = new ViewScroll(GalleryMain.this, ia.imgIds[0],g); ll.addView(detail,parm); g.setAdapter(ia); g.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) { ll.removeView(detail); detail = new ViewScroll(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 * */ public class ImageAdapter extends BaseAdapter { /*图片素材*/ public int[] imgIds = {R.drawable.jpg,R.drawable.pic}; private Context context; public ImageAdapter(Context context) { this.context = context; } @Override public int getCount() { return imgIds.length; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ImageView img = new ImageViewImp(context); img.setImageResource(imgIds[position]); img.setScaleType(ScaleType.CENTER); img.setLayoutParams(new Gallery.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 * */ public class ImageViewImp extends ImageView { private int alpha = 250; private boolean pressed = false; public ImageViewImp(Context context) { super(context); } Matrix m; public void show() { new Thread(){ public void 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(); } @Override public boolean onTouchEvent(MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) show(); return false; } @Override protected void onDraw(Canvas canvas) { Paint p = new Paint(); 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); } } public static Bitmap imageScale(Bitmap bitmap, int dst_w, int dst_h){ int src_w = bitmap.getWidth(); int src_h = bitmap.getHeight(); float scale_w = ((float)dst_w)/src_w; float scale_h = ((float)dst_h)/src_h; Matrix matrix = new Matrix(); matrix.postScale(scale_w, scale_h); Bitmap dstbmp = Bitmap.createBitmap(bitmap, 0, 0, src_w, src_h, matrix, true); return dstbmp; } }

 

 

各种xml ->布局-> style -> color

#FFFFFFFF #00FFFF #7F000000





你可能感兴趣的:(andriod)