您的位置:首页 > 移动开发 > Android开发

android TouchImageView 进阶

2016-01-11 17:24 405 查看
实现图片放大缩小控制按钮进行大小缩放,双击放大缩小,移动,多点(两点)缩放功能 

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();
}
}

@Override
protected 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() {

@Override
public void onLoadingStarted(String imageUri, View view) {
}

@Override
public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {
load_count++;
}

@Override
public 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_id
return;
}
//		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 - 1
if (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);
}

@Override
protected 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")
@Override
public 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);
// 防抖功能
// 如果两个手指头移动的距离同时都小于5
if (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+c
re[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转换成新的坐标,并存放于dst
matrix.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;
@Override
public 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;
}

@Override
protected 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;
}

@Override
protected 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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android