自定义imageview,实现多点缩放回弹

package laladin.album;import android.content.Context;import android.graphics.Bitmap;import android.util.FloatMath;import android.view.MotionEvent;import android.view.animation.AccelerateInterpolator;import android.view.animation.Animation;import android.view.animation.Animation.AnimationListener;import android.view.animation.ScaleAnimation;import android.view.animation.TranslateAnimation;import android.widget.ImageView;/** * ImageView Tonuch * @author Laladin.SYD * */public class MyImageView extends ImageView { static final int NONE = 0; // 拖动中 static final int DRAG = 1; // 缩放中 static final int ZOOM = 2; // 放大ing static final int BIGGER = 3; // 缩小ing static final int SMALLER = 4; //关闭缩放动画 static final int OPENSCALE=1; //关闭移动动画 static final int OPENTRANS=2; // 当前的事件 private int mode = NONE; // 两触点距离 private float beforeLenght; // 两触点距离 private float afterLenght; // 缩放的比例 X Y方向都是这个值 越大缩放的越快 private float scale = 0.06f; /* 处理拖动 变量 */ 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; /* Bitmap的宽高 */ private int bmWidth; private int bmHeight; // 处理超出边界的动画 private Bitmap bitmap; private float maxScale = 2.0f; private float minScale = 1.0f; //记录初始宽度,,用于缩放回弹 private int startWidth = 0; private float piovtX=0.5f; private float piovtY=0.5f; //默认开启所有动画 private int AnimSwitch=OPENSCALE|OPENTRANS; /** * 构造函数 * * @param context *相关上下文 * @param w *容器的宽 * @param h *容器的高 */ public MyImageView(Context context, int w, int h) { super(context); this.setPadding(0, 0, 0, 0); screenW = w; screenH = h; } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); //重置startWidth startWidth=0; bmWidth = bm.getWidth(); bmHeight = bm.getHeight(); if (bitmap != null && !bitmap.isRecycled()) bitmap.recycle(); bitmap = bm; } /** * 释放ImageView的Bitmap */ public void recycle() { setImageBitmap(null); if (bitmap != null && !bitmap.isRecycled()) bitmap.recycle(); } /** * 计算两点间的距离 */ 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); } private float[] center; /** * 计算两点间的中心点 */ private float[] centerPostion(MotionEvent event) { float[] center = new float[2]; float x = event.getX(0); float y = event.getY(0); float x1 = event.getX(1); float y1 = event.getY(1); /* x,y分别的距离 */ center[0] = Math.abs((x1 – x) / 2); center[1] = Math.abs((y1 – y) / 2); center[0] = Math.max(x, x1) – center[0]; center[1] = Math.max(y, y1) – center[1]; return center; } /** * 设置ImageView大小等于显示的内容大小 */ public void setRect() { float scale = Math.min((float) getWidth() / (float) bmWidth,(float) getHeight() / (float) bmHeight); int w = (int) ((float) bmWidth * scale) + 1; int h = (int) ((float) bmHeight * scale) + 1; // int t=(screenH-h)/2; // int l=(screenW-w)/2; int t = getTop(); int l = getLeft(); layout(l, t, l + w, t + h); } /** * 处理各种移动回弹 * * @param disX *X的偏移 * @param disY *Y的偏移 */ public void Rebound(int disX, int disY) { this.layout(getLeft() + disX, getTop() + disY, getLeft() + disX+ getWidth(), getTop() + disY + getHeight()); if((AnimSwitch&OPENTRANS)==0) return; trans = new TranslateAnimation(-disX, 0, -disY, 0); trans.setInterpolator(new AccelerateInterpolator()); trans.setDuration(300); this.startAnimation(trans); } /** * 处理各种缩放回弹 */ public boolean ReScale() { float scaleX = 1f; float scaleY = 1f; int width=getWidth(); int height=getHeight(); int l,t,r,b; if (center==null) return false; if (getWidth() > startWidth * maxScale) { while(getWidth()>startWidth * maxScale){ l = this.getLeft() + (int) (center[0] * this.getWidth()); t = this.getTop() + (int) (center[1] * this.getHeight()); r = this.getRight() – (int) ((scale – center[0]) * this.getWidth()); b = this.getBottom()- (int) ((scale – center[1]) * this.getHeight()); this.setFrame(l, t, r, b); } scaleX=(float)width/(float)getWidth(); scaleY=(float)height/(float)getHeight(); } if (getWidth() < startWidth * minScale) { while(getWidth() < startWidth * minScale){ l = this.getLeft() – (int) (center[0] * this.getWidth()); t = this.getTop() – (int) (center[1] * this.getHeight()); r = this.getRight() + (int) ((scale – center[0]) * this.getWidth()); b = this.getBottom()+ (int) ((scale – center[1]) * this.getHeight()); this.setFrame(l, t, r, b); } scaleX=(float)width/(float)getWidth(); scaleY=(float)height/(float)getHeight(); }if (scaleX == 1f && scaleY == 1f) return false; if((AnimSwitch&OPENSCALE)==0){ setRect(); onRebound(); return true; } ScaleAnimation scaleanim = new ScaleAnimation(scaleX, 1f, scaleY, 1f,ScaleAnimation.RELATIVE_TO_SELF, piovtX,ScaleAnimation.RELATIVE_TO_SELF, piovtY); scaleanim.setDuration(300); scaleanim.setInterpolator(new AccelerateInterpolator()); scaleanim.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation paramAnimation) {} @Override public void onAnimationRepeat(Animation paramAnimation) {} @Override public void onAnimationEnd(Animation paramAnimation) {setRect();onRebound(); }}); this.startAnimation(scaleanim); return true; } /** * 处理超范围回弹 */ private void onRebound() { /* 判断是否超出范围 并处理 */ int disX = 0, disY = 0; if (getHeight() < screenH) { disY = (screenH – getHeight()) / 2 – getTop(); } if (getWidth() < screenW) { disX = (screenW – getWidth()) / 2 – getLeft(); } if (getHeight() >= screenH) { if (getTop() > 0)disY = -getTop(); if (getBottom() < screenH)disY = screenH – getBottom(); } if (getWidth() >= screenW) { if (getLeft() > 0)disX = -getLeft(); if (getRight() < screenW)disX = screenW – getRight(); } //开始回弹 Rebound(disX, disY); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { // TODO Auto-generated method stub super.onLayout(changed, left, top, right, bottom); if (startWidth == 0) { startWidth = right – left; setRect(); AnimSwitch=0; onRebound(); AnimSwitch=OPENSCALE|OPENTRANS; } } /** * 处理触碰.. */ @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: /** 下面三句用于计算缩放中心点位置 **/ center = centerPostion(event); piovtX=center[0]/getWidth(); piovtY=center[1]/getHeight();center[0] = (center[0] / getWidth()) * scale; center[1] = (center[1] / getHeight()) * scale; if (spacing(event) > 10f) {mode = ZOOM;beforeLenght = spacing(event); } break; case MotionEvent.ACTION_UP: mode = NONE; setRect(); /* 判断是否超过缩放界限 */ if (!ReScale())onRebound(); break; case MotionEvent.ACTION_POINTER_UP: mode = NONE; break; case MotionEvent.ACTION_MOVE: /* 处理拖动 */ if (mode == DRAG) {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) { int l = 0, t = 0, r = 0, b = 0; if (flag == BIGGER) { l = this.getLeft() – (int) (center[0] * this.getWidth()); t = this.getTop() – (int) (center[1] * this.getHeight()); r = this.getRight() + (int) ((scale – center[0]) * this.getWidth()); b = this.getBottom()+ (int) ((scale – center[1]) * this.getHeight()); } else if (flag == SMALLER) { l = this.getLeft() + (int) (center[0] * this.getWidth()); t = this.getTop() + (int) (center[1] * this.getHeight()); r = this.getRight() – (int) ((scale – center[0]) * this.getWidth()); b = this.getBottom()- (int) ((scale – center[1]) * this.getHeight()); } this.setFrame(l, t, r, b); } /** * 实现处理拖动 */ private void setPosition(int left, int top, int right, int bottom) { this.layout(left, top, right, bottom); }}

那绿叶上的水珠,是思念的泪滴。

自定义imageview,实现多点缩放回弹

相关文章:

你感兴趣的文章:

标签云: