android TouchImageView 进阶

来源:互联网 发布:网站如何防止sql注入 编辑:程序博客网 时间:2024/05/29 16:30



实现图片放大缩小控制按钮进行大小缩放,双击放大缩小,移动,多点(两点)缩放功能 


DrawImageLayout 包含多张图片,可选择不同图片进行操作


部分代码:


<DrawImageLayout        android:id="@+id/template_main"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_below="@id/template_title"        android:layout_marginLeft="12dp"        android:layout_marginRight="12dp"        android:layout_marginTop="12dp" >    </DrawImageLayout>



import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.PaintFlagsDrawFilter;import android.graphics.drawable.BitmapDrawable;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.MotionEvent;import android.view.View;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.widget.FrameLayout;import android.widget.ImageView;import com.alibaba.fastjson.JSONObject;import com.example.touch.R;import com.nostra13.universalimageloader.core.ImageLoader;import com.nostra13.universalimageloader.core.assist.FailReason;import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;public class DrawImageLayout extends FrameLayout{private int id = 0;private int load_id = 0;private ImageInfo[] pats = null;/** 手指头的x坐标 */private float X = 0f;/** 手指头的y坐标 */private float Y = 0f;/** 按下时手指头的x坐标与图片的x坐标的距离 **/private float CX = 0f;/** 按下时手指头的y坐标与图片的y坐标的距离 **/private float CY = 0f;private int width;private int height;public DrawImageLayout(Context context) {super(context);}public DrawImageLayout(Context context, AttributeSet attrs) {super(context, attrs);}public DrawImageLayout(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}//设置界面为正方形
public void setDisplayMetrics(DisplayMetrics metric) {try {Class<?> clazz = DrawImageLayout.this.getLayoutParams().getClass();int rightMargin = ((Integer) clazz.getField("rightMargin").get(DrawImageLayout.this.getLayoutParams())).intValue();int leftMargin = ((Integer) clazz.getField("leftMargin").get(DrawImageLayout.this.getLayoutParams())).intValue();width = metric.widthPixels - rightMargin - leftMargin;height = width;this.getLayoutParams().width = width;this.getLayoutParams().height = height;} catch (Exception e) {e.printStackTrace();}}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();//loadImage();//gg}private int load_count = 0;public int getLoadCount() {return this.load_count;}public int getPatsCount() {if (null == pats) {return 0;}return this.pats.length;}public void loadImage() {if (null == pats) {return;}if(load_id != id){return;}load_count = 0;id++;for (int i = 0; i < pats.length; i++) {final int idx = i;final OptionImageView iv = new OptionImageView(DrawImageLayout.this.getContext(), pats[i]);if(pats[i] != null){ImageLoader.getInstance().loadImage(pats[i].getPath(), BitmapUtils.getOptions(),new SimpleImageLoadingListener() {@Overridepublic void onLoadingStarted(String imageUri, View view) {}@Overridepublic void onLoadingFailed(String arg0, View arg1, FailReason arg2) {load_count++;}@Overridepublic void onLoadingComplete(String arg0, View img, Bitmap bmp) {synchronized (DrawImageLayout.this) {initIv(iv,idx,bmp);SDCardUtils.saveImage(arg0.replaceAll("://","").replaceAll("/",""), bmp);}}});//}}}init = true;}/** * 初始化OptionImageView */private void initIv(OptionImageView iv,int idx, Bitmap bmp){if (id != DrawImageLayout.this.id) {//load_idreturn;}//OptionImageView iv = (OptionImageView)img;ImageInfo info = DrawImageLayout.this.pats[idx];iv.setPiority(idx);iv.setTag(idx);LayoutParams pa = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);float s = 1.0F;if (bmp.getWidth() > bmp.getHeight()) {s = (float)pats[idx].width / (float)bmp.getWidth();int tar_height = (int)(bmp.getHeight() * s);pats[idx].setHeight(tar_height);} else if(bmp.getWidth() < bmp.getHeight()) {s = (float)pats[idx].height / (float)bmp.getHeight();int tar_width = (int)(bmp.getWidth() * s);pats[idx].setWidth(tar_width);} else {s = (float)pats[idx].width / (float)bmp.getWidth();}float preX = pats[idx].getX();float preY = pats[idx].getY();iv.setPreX(preX);iv.setPreY(preY);iv.setmWidth(pats[idx].getWidth());iv.setmHeight(pats[idx].getHeight());iv.setLayoutParams(pa);//idx == DrawImageLayout.this.pats.length - 1if (idx == DrawImageLayout.this.pats.length - 1) {iv.setDrawBorder(true);topImageInfo = iv;cur_check = idx;}info.setBit(bmp);iv.setImageBitmap(info.getBit());iv.getmMatrix().postScale(s, s);iv.setImageMatrix(iv.getmMatrix());iv.getmMatrix().postTranslate(preX - pats[idx].getWidth() / 2, preY - pats[idx].getHeight() / 2);iv.setImageMatrix(iv.getmMatrix());if(load_count < pats.length){iv.clearAnimation();Animation anim = selectAnimation(idx);if(anim != null){iv.startAnimation(anim);}this.addView(iv, pa);load_count++;if(load_count == pats.length){load_id++;}}}/** * 动画 * @param idx * @return */private Animation selectAnimation(int idx){int x = pats[idx].getX();int y = pats[idx].getY();Animation anim = null;if(x <= y){anim = AnimationUtils.loadAnimation(YiApplication.getInstance().getApplicationContext(),R.anim.fade_in);}else {anim = AnimationUtils.loadAnimation(YiApplication.getInstance().getApplicationContext(),R.anim.fade_in2);}return anim;}public OptionImageView getCheckImg() {if (-1 == cur_check) {return null;}return topImageInfo;}private boolean init = false;public boolean isInit() {return init;}/** * 重置 */public void reset() {this.removeAllViews();this.invalidate();loadImage();}/** * 置顶 */public void top() {OptionImageView[] ivs = new OptionImageView[this.getChildCount()];OptionImageView t = findTopImage();int idx = 0;for (int i = 0; i < this.getChildCount(); i++) {if (this.getChildAt(i) == t) {continue;}ivs[idx] = (OptionImageView) this.getChildAt(i);idx++;}ivs[idx] = t;this.removeAllViews();for (int i = 0; i < ivs.length; i++) {this.addView(ivs[i]);}}public void up() {OptionImageView t = findTopImage();int idx = 0;for (int i = 0; i < this.getChildCount(); i++) {if (this.getChildAt(i) == t) {idx = i;break;}}if (this.getChildCount() - 1 < idx + 1) {return;}View v1 = this.getChildAt(idx + 1);View v2 = this.getChildAt(idx);this.removeView(v1);this.removeView(v2);this.addView(v2, idx);this.addView(v1, idx);}public void down() {OptionImageView t = findTopImage();int idx = 0;for (int i = 0; i < this.getChildCount(); i++) {if (this.getChildAt(i) == t) {idx = i;break;}}if (0 > idx - 1) {return;}View v1 = this.getChildAt(idx - 1);View v2 = this.getChildAt(idx);this.removeView(v1);this.removeView(v2);idx = idx - 1;if (this.getChildCount() - 1 < idx) {idx = this.getChildCount();}this.addView(v1, idx);this.addView(v2, idx);}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();}public void setImages(ImageInfo[] paths) {if (paths == null)return;if(pats != null){for(int i = 0; i < pats.length; i++){ImageInfo info = pats[i];Bitmap bit = info.getBit();if(bit != null && !bit.isRecycled()){bit.recycle();bit = null;}}}pats = paths;}public ImageInfo[] getImages(){return pats;}private OptionImageView topImageInfo = null;private float[] rotalP = null;private float[] rotalP_2 = null;private float preLength = 480.0f;private float length = 480.0f;private float preCos = 0f;private float cos = 0f;private boolean bool = true;private boolean Begin = true;private float[] p1 = new float[2];private float[] p2 = new float[2];@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {if (null == findTopImage()) {return true;}if(isChange){return true;}switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN:// LogUtil.d(tag, "onTouchEvent() -- 第一根手指点下...");actionDown(event);break;// 副点按下case MotionEvent.ACTION_POINTER_DOWN:topImageInfo.getSavedMatrix().set(topImageInfo.getmMatrix());p2[0] = event.getX(1);p2[1] = event.getY(1);topImageInfo.setMood(OptionImageView.MOOD_ACTION_POINTERDOWN);// LogUtil.d(tag,// "onTouchEvent() -- 副手指点下... p2[0]:"+p2[0]+"; p2[1]:"+p2[1]);break;case MotionEvent.ACTION_UP:// LogUtil.d(tag, "onTouchEvent() -- 手指头抬起..");CX = 0f;CY = 0f;topImageInfo.setMood(OptionImageView.MOOD_ACTION_UP);Begin = false;bool = true;return true;case MotionEvent.ACTION_POINTER_UP:topImageInfo.setMood(OptionImageView.MOOD_ACTION_POINTERUP);// LogUtil.d(tag, "onTouchEvent() -- 副手指头抬起..");Begin = false;bool = true;return true;case MotionEvent.ACTION_MOVE:// LogUtil.d(tag, "onTouchEvent() -- ACTION_MOVE..");boolean b = actionMove(event);if (b)return b;break;}// LogUtil.i(tag, "onTouchEvent() -- 开始刷新..");topImageInfo.setImageMatrix(topImageInfo.getmMatrix());// invalidate();return true;}private boolean actionMove(MotionEvent event) {if (Begin && topImageInfo.getMood() == OptionImageView.MOOD_ACTION_DOWN) {// topImageInfo.setMood(OptionImageView.MOOD_ACTION_MOVE);if (spacingSingel(event.getX(0), event.getY(0), p1[0], p1[1]) < 5)return true;p1[0] = event.getX(0);p1[1] = event.getY(0);// LogUtil.d(tag,// "actionMove() -- move.. preX:"+topImageInfo.getPreX()+"; preY:"+topImageInfo.getPreY());// 1根手指头移动this.X = event.getX();this.Y = event.getY();topImageInfo.getmMatrix().set(topImageInfo.getSavedMatrix());rotalP = rotalPoint(new float[] { this.X, this.Y }, topImageInfo.getPreX(), topImageInfo.getPreY(), topImageInfo.getmMatrix());// LogUtil.i(tag, "actionMove() -- x:" + rotalC[0] + ";y:" +// rotalC[1]);float oldPreX = topImageInfo.getPreX();float oldPreY = topImageInfo.getPreY();topImageInfo.setPreX(X + CX);topImageInfo.setPreY(Y + CY);topImageInfo.transFrame(topImageInfo.getPreX() - oldPreX, topImageInfo.getPreY() - oldPreY);}// 两指移动if (topImageInfo.getMood() == OptionImageView.MOOD_ACTION_POINTERDOWN) {float p1J = spacingSingel(event.getX(0), event.getY(0), p1[0], p1[1]);float p2J = spacingSingel(event.getX(1), event.getY(1), p2[0], p2[1]);// LogUtil.d(tag,// "onTouchEvent() -- 副手指  p2[0]:"+p2[0]+"; p2[1]:"+p2[1]+"; 最新的x:"+event.getX(1)+"; y:"+event.getY(1));// LogUtil.d(tag,// "onTouchEvent() -- 两个点move.. 手指1移动的距离 :"+p1J+";  手指2移动的距离 :"+p2J);// 防抖功能// 如果两个手指头移动的距离同时都小于5if (p1J < 5 && p2J < 5) {return true;}// LogUtil.d(tag,// "actionMove() -- MOOD_ACTION_POINTERDOWN.. preX:"+topImageInfo.getPreX()+"; preY:"+topImageInfo.getPreY());p1[0] = event.getX(0);p1[1] = event.getY(0);p2[0] = event.getX(1);p2[1] = event.getY(1);// topImageInfo.getmMatrix().set(topImageInfo.getSavedMatrix());rotalP = rotalPoint(new float[] { event.getX(0), event.getY(0) }, topImageInfo.getPreX(), topImageInfo.getPreY(), topImageInfo.getmMatrix());rotalP_2 = rotalPoint(new float[] { event.getX(1), event.getY(1) }, topImageInfo.getPreX(), topImageInfo.getPreY(), topImageInfo.getmMatrix());if ((Math.abs(rotalP[0] - topImageInfo.getPreX()) < topImageInfo.getmWidth() / 2f)&& (Math.abs(rotalP[1] - topImageInfo.getPreY()) < topImageInfo.getmHeight() / 2f)&& (Math.abs(rotalP_2[0] - topImageInfo.getPreX()) < topImageInfo.getmWidth() / 2f)&& (Math.abs(rotalP_2[1] - topImageInfo.getPreY()) < topImageInfo.getmHeight() / 2f) || true) {if (bool) {// 第一次两指头点来,记录下角度和长度preLength = spacing(event);preCos = cos(event);bool = false;}// 获取最新角度和长度length = spacing(event);cos = cos(event);// LogUtil.i(tag, "actionMove() -- 旋转角度:"+cos);float width = topImageInfo.getmWidth();float height = topImageInfo.getmHeight();// LogUtil.i(tag,// "actionMove() -- width:"+width+"; height:"+height);// 放大和缩小if (length - preLength != 0) {float scW = (1.0f + (length - preLength) / length);topImageInfo.getmMatrix().postScale(scW, scW, topImageInfo.getPreX(), topImageInfo.getPreY());// scale(width/2, height/2, topImageInfo.getPreX(),// topImageInfo.getPreY(), topImageInfo.getmMatrix());topImageInfo.scalFrame(scW);}// 旋转if (Math.abs(cos) > 5 && Math.abs(cos) < 177&& Math.abs(cos - preCos) < 15) {topImageInfo.getmMatrix().postRotate(cos - preCos);this.getT(width / 2f, height / 2f, topImageInfo.getPreX(), topImageInfo.getPreY(), topImageInfo.getmMatrix());topImageInfo.rotateFrame(width, height);}preCos = cos;preLength = length;}}if(!StringUtils.isEmpty(UserBean.USER_CACHE)){//加入模板缓存TemplateUtils.saveTemplate(UserBean.USER_ID, pats,temp_url);}return false;}@SuppressWarnings("deprecation")private boolean actionDown(MotionEvent event) {try {order(event);} catch (Exception e) {return true;}/*设置最顶上的imageview*/topImageInfo = findTopImage();this.X = event.getX();this.Y = event.getY();int a = 0;for (int i = 0; i < getChildCount(); i++) {OptionImageView optionImageView = (OptionImageView) getChildAt(i);if(optionImageView.isOnView(this.X,this.Y)){optionImageView.setAlpha(255);   }else{a++;if(a==getChildCount()){/*当点击范围都不在每个OptionImageView范围内*/a = 0;for (int j = 0; j < getChildCount(); j++) {OptionImageView optionImageView2 = (OptionImageView) getChildAt(j);optionImageView2.setAlpha(255);   }}else{optionImageView.setAlpha(150);  }}}CX = topImageInfo.getPreX() - event.getX();CY = topImageInfo.getPreY() - event.getY();topImageInfo.getSavedMatrix().set(topImageInfo.getmMatrix());Begin = true;p1[0] = event.getX();p1[1] = event.getY();topImageInfo.setMood(OptionImageView.MOOD_ACTION_DOWN);return true;}/** * 找到优先级最高的view *  * @return */private OptionImageView findTopImage() {int pre = 0;OptionImageView temp = null;for (int i = 0; i < getChildCount(); i++) {OptionImageView my = (OptionImageView) getChildAt(i);if (my.getPiority() > pre) {pre = my.getPiority();temp = my;}}if(temp != null){cur_check = Integer.parseInt(temp.getTag().toString());}return temp;}/** *  * @param preX *            图片中心点x * @param preY *            图片中心点y * @param x *            手指头x坐标加上移动的x轴距离 * @param y *            手指头y坐标加上移动的y轴距离 * @param iv * @return */public float[] getT(float preX, float preY, float x, float y, Matrix iv) {float[] re = new float[2];float[] matrixArray = new float[9];iv.getValues(matrixArray);float a = x - preX * matrixArray[0] - preY * matrixArray[1];float b = y - preX * matrixArray[3] - preY * matrixArray[4];matrixArray[2] = a;matrixArray[5] = b;iv.setValues(matrixArray);re[0] = a;re[1] = b;return re;}/** * 得到旋转点 *  * @param p *            当前手指头的x,y坐标 * @param X *            图片之前的x坐标 * @param Y *            图片之前的y坐标 * @param matrix * @return */public float[] rotalPoint(float[] p, float X, float Y, Matrix matrix) {float re[] = new float[2];float matrixArray[] = new float[9];matrix.getValues(matrixArray);// LogUtil.i(tag,// "rotalPoint() -- matrixArray[0]: "+matrixArray[0]+"; matrixArray[1] :"+matrixArray[1]// +"; matrixArray[2] :"+matrixArray[1] );// LogUtil.i(tag,// "rotalPoint() -- matrixArray[3]: "+matrixArray[3]+"; matrixArray[4] :"+matrixArray[4]// +"; matrixArray[5] :"+matrixArray[5] );// 计算出x,y的差值float a = p[0] - X;float b = p[1] - Y;// 矩阵公式// x' = a*x+b*y+cre[0] = a * matrixArray[0] - b * matrixArray[1] + X;re[1] = -a * matrixArray[3] + b * matrixArray[4] + Y;// re[0] = a * matrixArray[0] + b * matrixArray[1] + X;// re[1] = a * matrixArray[3] + b * matrixArray[4] + Y;// LogUtil.i(tag, "rotalPoint() -- re[0]: "+re[0]+"; re[1] :"+re[1]// +"; a :"+a+"; b:"+b +";X:"+X+";Y:"+Y );return re;}/** * 计算长度 *  * @param event * @return */private float spacing(MotionEvent event) {float x = event.getX(0) - event.getX(1);float y = event.getY(0) - event.getY(1);return (float) Math.sqrt(x * x + y * y);}private float spacingSingel(float newX, float newY, float oldX, float oldY) {float x = newX - oldX;float y = newY - oldY;return (float) Math.sqrt(x * x + y * y);}/** * 计算余弦 *  * @param event * @return */private float cos(MotionEvent event) {if ((event.getX(0) - event.getX(1)) * (event.getY(0) - event.getY(1)) > 0) {return (float) ((float) Math.acos(Math.abs(event.getX(0) - event.getX(1)) / spacing(event))/ Math.PI * 180f);}if ((event.getX(0) - event.getX(1)) * (event.getY(0) - event.getY(1)) < 0) {return (float) ((float) Math.acos(-Math.abs(event.getX(0) - event.getX(1)) / spacing(event)) / Math.PI * 180f);}if (event.getX(0) - event.getX(1) == 0) {return (float) 90f;}if (event.getY(0) - event.getY(1) == 0) {return 0f;}return 45f;}public float[] scale(float preX, float preY, float x, float y, Matrix matrix) {float[] matrixArray = new float[9];matrix.getValues(matrixArray);float a = x - preX;float b = y - preY;matrixArray[2] = a;matrixArray[5] = b;matrix.setValues(matrixArray);float[] scale = { a, b };return scale;}public void setToO(Matrix matrix) {float[] matrixArray = new float[9];matrix.getValues(matrixArray);float a = 0f;float b = 0f;matrixArray[2] = a;matrixArray[5] = b;matrix.setValues(matrixArray);}private int cur_check = -1;public void order(MotionEvent event) {OptionImageView temp = null;// LogUtil.i(tag,// "order() -- event.x:"+event.getX()+";event.y:"+event.getY());for (int i = (getChildCount() - 1); i > -1; i--) {temp = (OptionImageView) getChildAt(i);// LogUtil.i(tag,// "order() -- i:"+i+";  width:"+temp.getmWidth()+"; height:"+temp.getmHeight());// rotalP = rotalPoint(new float[] { event.getX(), event.getY() },// temp.getPreX(),// temp.getPreY(),// temp.getImageMatrix());// 获取触控点float tx = event.getX();float ty = event.getY();// 存放新坐标的数组float[] dst = new float[2];// 触控点坐标的数组float[] src = { tx, ty };Matrix matrix = new Matrix();// 获取绘制图片的Matrix,并转换mantrix// set inverse to be the inverse of this matrix.if (temp.getImageMatrix().invert(matrix)) {// 触控坐标根据matrix转换成新的坐标,并存放于dstmatrix.mapPoints(dst, src);}boolean isSelect = false;float[] ma = new float[9];temp.getImageMatrix().getValues(ma);// LogUtil.i(tag,// "order() -- dst[0]:"+dst[0]+" dst[1]:"+dst[1]+"; tx:"+tx+"; ty:"+ty);/** * 判断是否击中bitmap */if (dst[0] >= 0 && dst[0] <= temp.getmWidth() && dst[1] >= 0 && dst[1] <= temp.getmHeight()) {isSelect = true;cur_check = Integer.parseInt(temp.getTag().toString());}if (isSelect) {for (int j = (getChildCount() - 1); j > -1; j--) {OptionImageView child = (OptionImageView) getChildAt(j);if (child.getPiority() > temp.getPiority()) {child.setPiority(child.getPiority() - 1);}child.setDrawBorder(false);child.invalidate();}temp.setPiority(getChildCount() - 1);temp.setDrawBorder(true);return;}}}public class ImageInfo {private String path;/** 图片宽 **/private int width;/** 图片高 **/private int height;/** 左上角的x初始坐标 **/private int x;/** 左上角的y初始坐标 **/private int y;private int src_x;private int src_y;private int src_width;private int src_height;private Bitmap bit = null;private DisplayMetrics metric;private JSONObject option;private int tag;@Overridepublic String toString() {return "ImageInfo [path=" + path + ", width=" + width + ", height="+ height + ", x=" + x + ", y=" + y + ", src_x=" + src_x+ ", src_y=" + src_y + ", src_width=" + src_width+ ", src_height=" + src_height + ", bit=" + bit+ ", metric=" + metric + ", option=" + option + "]";}public void reset() {this.width = this.src_width;this.height = this.src_height;}/** * 200px为基准. 该基准为宽度的1/3.<br /> * 坐标位置以600*600区域为准.写下x与y值. *  * @param width * @param height * @param x * @param y * @param path * @param metric */public ImageInfo(int width, int height, int x, int y, String path, DisplayMetrics metric, JSONObject option,int tag) {this.metric = metric;this.width = (int) ((width / 200.0F) * (DrawImageLayout.this.width / 3.0F));this.height = (int) ((height / 200.0F) * (DrawImageLayout.this.width / 3.0F));this.x = (int) ((width / 200.0F) * (metric.density * 55)/*该位置需要与密度比值计算, 基数55*/) + (int) (x * (DrawImageLayout.this.width / 600.0F));this.y = (int) ((width / 200.0F) * (metric.density * 56.25)/*该位置需要与密度比值计算, 基数56.25*/) + (int) (y * (DrawImageLayout.this.height / 600.0F));this.path = path;this.option = option;this.src_width = this.width;this.src_height = this.height;this.src_x = this.x;this.src_y = this.y;this.tag = tag;}public int getTag(){return tag;}public int getSrc_x() {return src_x;}public int getSrc_y() {return src_y;}public int getSrc_width() {return src_width;}public int getSrc_height() {return src_height;}public String getPath() {return path;}public int getWidth() {return width;}public void setWidth(int width) {this.width = width;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public Bitmap getBit() {return bit;}public void setBit(Bitmap bit) {this.bit = bit;}public JSONObject getOption() {return option;}}private boolean isChange = false;/** * 隐藏红色边框,设置每件商品的透明度 */@SuppressWarnings("deprecation")public void hiddenCurCK() {OptionImageView view = getCheckImg();if (null != view){view.setDrawBorder(false);view.postInvalidate();}for (int i = 0; i < getChildCount(); i++) {OptionImageView optionImageView = (OptionImageView) getChildAt(i);optionImageView.setAlpha(255);   }}public static class OptionImageView extends ImageView {/** 左上角的x初始坐标 **/private float preX;/** 左上角的y初始坐标 **/private float preY;/** 图片宽 **/private float mWidth;/** 图片高 **/private float mHeight;private Matrix mMatrix = new Matrix();private Matrix savedMatrix = new Matrix();private Matrix scaleMatrix = new Matrix();/** 优先级 **/private int piority;boolean isDrawBorder = false;boolean isInit = false;private int mood = 0;// 手指按下public static final int MOOD_ACTION_DOWN = 1;// 副手指按下public static final int MOOD_ACTION_POINTERDOWN = 2;// 副手指离开屏幕public static final int MOOD_ACTION_POINTERUP = 3;// 手指离开屏幕public static final int MOOD_ACTION_UP = 4;// 手指离在屏幕上滑动public static final int MOOD_ACTION_MOVE = 5;private ImageInfo info;/** * 存储边框各个点的坐标,依次为左上、右上、右下、左下 */private float[] mFrame = new float[8];public OptionImageView(Context context, ImageInfo info) {super(context);this.info = info;// 设置ScaleType为ScaleType.MATRIX,这一步很重要this.setScaleType(ScaleType.MATRIX);}// 将图片加灰色的边框private int color;public void setColor(int color) {this.color = color;}public ImageInfo getInfo() {return info;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// LogUtil.i(tag, "onDraw() -- isDrawBorder:"+isDrawBorder);// 根据MyImageView来获取bitmap对象// AsyncDrawable bd = (AsyncDrawable)this.getDrawable();if (!isInit) {isInit = true;this.mWidth = info.width;this.mHeight = info.height;setDefaultFrame(mWidth / 2, mHeight / 2);}dra(canvas);}public float getPreX() {return preX;}public void setPreX(float preX) {this.preX = preX;}public float getPreY() {return preY;}public void setPreY(float preY) {this.preY = preY;}public int getColor() {return color;}public float getmWidth() {// 根据MyImageView来获取bitmap对象BitmapDrawable bd = (BitmapDrawable) this.getDrawable();if (bd != null) {this.mWidth = bd.getBitmap().getWidth();}return mWidth;}public void setmWidth(float mWidth) {this.mWidth = mWidth;}public float getmHeight() {// 根据MyImageView来获取bitmap对象BitmapDrawable bd = (BitmapDrawable) this.getDrawable();if (bd != null) {this.mHeight = bd.getBitmap().getHeight();}return mHeight;}public void setmHeight(float mHeight) {this.mHeight = mHeight;}public int getPiority() {return piority;}public void setPiority(int piority) {this.piority = piority;}/** * 设置默认边框,基于中心点的未经旋转的边框 *  * @param desX *            中心点距左右边界的距离 * @param desY *            中心点距上下边界的距离 */public void setDefaultFrame(float desX, float desY) {mFrame[0] = this.preX - desX;mFrame[1] = this.preY - desY;mFrame[2] = this.preX + desX;mFrame[3] = this.preY - desY;mFrame[4] = this.preX + desX;mFrame[5] = this.preY + desY;mFrame[6] = this.preX - desX;mFrame[7] = this.preY + desY;}/** * 移动边框 *  * @param offsetX *            X坐标移动的距离 * @param offsetY *            Y坐标移动的距离 */public void transFrame(float offsetX, float offsetY) {mFrame[0] += offsetX;mFrame[1] += offsetY;mFrame[2] += offsetX;mFrame[3] += offsetY;mFrame[4] += offsetX;mFrame[5] += offsetY;mFrame[6] += offsetX;mFrame[7] += offsetY;}public void scalFrame(float scale) {rotateFrame(mWidth, mHeight);}/** * 旋转边框,旋转前先先重置为正常未经旋转的边框,然后根据matrix的旋转值进行旋转 x = x0*cosα + y0*sinα y = * y0*cosα + x0*sinα *  * 矩阵表示如下: x cosα -sinα 0 x0 y = sinα cosα 0 y0 1 0 0 1 1 */public void rotateFrame(float width, float height) {// 设置未经旋转的边框各点坐标值setDefaultFrame(width / 2f, height / 2f);float[] temp = new float[mFrame.length];System.arraycopy(mFrame, 0, temp, 0, mFrame.length);// 根据旋转后的matrix值,设置旋转后的边框各点坐标值float[] matrixArray = new float[9];this.mMatrix.getValues(matrixArray);mFrame[0] = temp[0] * matrixArray[0] + temp[1] * matrixArray[1];mFrame[1] = temp[1] * matrixArray[4] + temp[0] * matrixArray[3];mFrame[2] = temp[2] * matrixArray[0] + temp[3] * matrixArray[1];mFrame[3] = temp[3] * matrixArray[4] + temp[2] * matrixArray[3];mFrame[4] = temp[4] * matrixArray[0] + temp[5] * matrixArray[1];mFrame[5] = temp[5] * matrixArray[4] + temp[4] * matrixArray[3];mFrame[6] = temp[6] * matrixArray[0] + temp[7] * matrixArray[1];mFrame[7] = temp[7] * matrixArray[4] + temp[6] * matrixArray[3];// 根据matrix的偏移值,将边框旋转后产生的偏移再重置回去if (matrixArray[2] > mFrame[0]) {float offsetX = matrixArray[2] - mFrame[0];float offsetY = mFrame[1] - matrixArray[5];mFrame[0] += offsetX;mFrame[1] -= offsetY;mFrame[2] += offsetX;mFrame[3] -= offsetY;mFrame[4] += offsetX;mFrame[5] -= offsetY;mFrame[6] += offsetX;mFrame[7] -= offsetY;} else {float offsetX = mFrame[0] - matrixArray[2];float offsetY = matrixArray[5] - mFrame[1];mFrame[0] -= offsetX;mFrame[1] += offsetY;mFrame[2] -= offsetX;mFrame[3] += offsetY;mFrame[4] -= offsetX;mFrame[5] += offsetY;mFrame[6] -= offsetX;mFrame[7] += offsetY;}}/** * 根据传入的x、y判断是否在控件里边 *  * @param x * @param y * @return */public boolean isOnView(float x, float y) {Matrix inMatrix = new Matrix();// inMatrix.set(mMatrix);mMatrix.invert(inMatrix);float[] xy = new float[2];inMatrix.mapPoints(xy, new float[] { x, y });if (xy[0] > 0 && xy[0] < mWidth && xy[1] > 0 && xy[1] < mHeight) {// LogUtil.i(tag, "isOnView() -- 在区域内...");return true;} else {// LogUtil.i(tag, "isOnView() -- 不在区域内...");}return false;}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();// LogUtil.i(tag, "onAttachedToWindow() -- dw:"+getDrawable());}public float[] getmFrame() {return mFrame;}public Matrix getmMatrix() {return mMatrix;}// public void setmMatrix(Matrix mMatrix) {// this.mMatrix = mMatrix;// }class Point {float x0, y0, x1, y1, x2, y2, x3, y3;}private void drawAl(Point point, Canvas canvas, int color, int alpha) {// LogUtil.i(tag, "drawAl()");Paint paint = new Paint();paint.setAntiAlias(true);paint.setColor(color);paint.setStyle(Style.STROKE);paint.setStrokeWidth(4);canvas.drawLine(point.x0, point.y0, point.x1, point.y1, paint);canvas.drawLine(point.x1, point.y1, point.x2, point.y2, paint);canvas.drawLine(point.x2, point.y2, point.x3, point.y3, paint);canvas.drawLine(point.x3, point.y3, point.x0, point.y0, paint);// canvas.drawPath(p, paint);}private void dra(Canvas canvas) {canvas.setDrawFilter(new PaintFlagsDrawFilter(0,Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));Point point = new Point();point.x0 = mFrame[0];point.y0 = mFrame[1];point.x1 = mFrame[2];point.y1 = mFrame[3];point.x2 = mFrame[4];point.y2 = mFrame[5];point.x3 = mFrame[6];point.y3 = mFrame[7];int color = Color.parseColor("#f977a7");if (!isDrawBorder) {color = Color.parseColor("#00000000");}drawAl(point, canvas, color, 0);}public void setDrawBorder(boolean isDrawBorder) {this.isDrawBorder = isDrawBorder;}public Matrix getSavedMatrix() {return savedMatrix;}public void setSavedMatrix(Matrix savedMatrix) {this.savedMatrix = savedMatrix;}public int getMood() {return mood;}public void setMood(int mood) {this.mood = mood;}public Matrix getScaleMatrix() {return scaleMatrix;}public void setScaleMatrix(Matrix scaleMatrix) {this.scaleMatrix = scaleMatrix;}}}


0 0
原创粉丝点击