我的问题与:
最相似Android 4.3 ImageView ScaleType.MATRIX
还有回声:
android zoom image using matrix
但是,使用这些答案的解决方案已经解决了我的问题。
我正在使用Mike Ortiz的TouchImageView的修改版本,允许双击和常规缩放手势来缩放我的ImageView。对于Android 4.2.2及更低版本,注释掉“setScaleType(ScaleType.MATRIX)”就好了,图像在ImageView中居中,你可以随意放大和缩小。但是,取消注释会导致ImageView的图像大小不正确。所有这一切都很好,因为我刚离开那条线进行评论,一切正常。
但是,从Android 4.3开始,如果没有setScaleType(ScaleType.MATRIX),则无法进行缩放。所以我不得不取消注释那条线,但是我从未解决的旧问题又回来了。
所以,首先,当我所做的只是设置ScaleType时,为什么我的计算无法产生正确的图像/ ImageView比率?第二,为什么在没有设置比例类型的情况下它会在4.2.2上变焦得很好,但在4.3上,它不会?最后,有人可以给我一些资源来了解更多关于ScaleType.MATRIX真正做的事情吗?我已经阅读了一些消息来源,并做了一些谷歌搜索,但并没有完全掌握它。
提前感谢您,以及以下代码。
public class TouchImageView extends ImageView {
Matrix matrix = new Matrix();
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// Remember some things for zooming
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 10f;
float[] floatArray;
float unusedWidth, unusedHeight;
float imageViewWidth, imageViewHeight;
float initialScale = 1f;
float right, bottom, origWidth, origHeight, imageWidth, imageHeight;
boolean zoomedInLastTime = false;
PointF zoomCenter;
ScaleGestureDetector mScaleDetector;
GestureDetector mDetector;
Context context;
public TouchImageView(Context context) {
super(context);
sharedConstructing(context);
}
public TouchImageView(Context context, AttributeSet attrs) {
super(context, attrs);
sharedConstructing(context);
}
private void sharedConstructing(Context context) {
super.setClickable(true);
this.context = context;
setScaleType(ScaleType.MATRIX);
//matrix = this.getImageMatrix();
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
//this is an empty GestureDetector
mDetector = new GestureDetector(this.context, new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent motionEvent) {
return false;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
return false;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent2, float v, float v2) {
return false;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
}
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent2, float v, float v2) {
return false;
}
}, null, true);
mDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener(){
@Override
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
return false;
}
@Override
public boolean onDoubleTap(MotionEvent motionEvent) {
Log.d("TouchImageView", "double tap heard");
PointF currentTapLocation = new PointF(motionEvent.getX(), motionEvent.getY());
if (!zoomedInLastTime){
(new ScaleListener()).scaleIt(3f,currentTapLocation.x,currentTapLocation.y);
zoomCenter = currentTapLocation;
zoomedInLastTime = true;
}else {
(new ScaleListener()).scaleIt(.33f, zoomCenter.x, zoomCenter.y);
zoomedInLastTime = false;
}
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent motionEvent) {
return false;
}
});
matrix.setTranslate(1f, 1f);
floatArray = new float[9];
setImageMatrix(matrix);
setOnTouchListener(new DoubleTapPinchZoomListener());
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
if(bm != null) {
if (Build.VERSION.SDK_INT > 17){
imageWidth = bm.getWidth();
imageHeight = bm.getHeight();
} else {
imageWidth = 2*bm.getWidth();
imageHeight = 2*bm.getHeight();
}
}
}
public void setMaxZoom(float x)
{
maxScale = x;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
mode = ZOOM;
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
float mScaleFactor = detector.getScaleFactor();
scaleIt(mScaleFactor, detector.getFocusX(), detector.getFocusY());
return true;
}
public void scaleIt(float mScaleFactor, float focusx, float focusy){
float origScale = initialScale;
initialScale *= mScaleFactor;
if (initialScale > maxScale) {
initialScale = maxScale;
mScaleFactor = maxScale / origScale;
} else if (initialScale < minScale) {
initialScale = minScale;
mScaleFactor = minScale / origScale;
}
right = imageViewWidth * initialScale - imageViewWidth - (2 * unusedWidth * initialScale);
bottom = imageViewHeight * initialScale - imageViewHeight - (2 * unusedHeight * initialScale);
if (origWidth * initialScale <= imageViewWidth || origHeight * initialScale <= imageViewHeight) {
matrix.postScale(mScaleFactor, mScaleFactor, imageViewWidth / 2, imageViewHeight / 2);
if (mScaleFactor < 1) {
matrix.getValues(floatArray);
float x = floatArray[Matrix.MTRANS_X];
float y = floatArray[Matrix.MTRANS_Y];
if (mScaleFactor < 1) {
if (Math.round(origWidth * initialScale) < imageViewWidth) {
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
} else {
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
}
}
}
} else {
matrix.postScale(mScaleFactor, mScaleFactor, focusx, focusy);
matrix.getValues(floatArray);
float x = floatArray[Matrix.MTRANS_X];
float y = floatArray[Matrix.MTRANS_Y];
if (mScaleFactor < 1) {
if (x < -right)
matrix.postTranslate(-(x + right), 0);
else if (x > 0)
matrix.postTranslate(-x, 0);
if (y < -bottom)
matrix.postTranslate(0, -(y + bottom));
else if (y > 0)
matrix.postTranslate(0, -y);
}
}
}
}
@Override
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
imageViewWidth = MeasureSpec.getSize(widthMeasureSpec);
imageViewHeight = MeasureSpec.getSize(heightMeasureSpec);
/*RectF drawableRect = new RectF(0, 0, imageWidth, imageHeight);
RectF viewRect = new RectF(0, 0, imageViewWidth, imageViewHeight);
//draw the image in the view
matrix.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER);*/
//Fit to screen.
float scale;
float scaleX = (float) imageViewWidth / (float)(imageWidth);
float scaleY = (float) imageViewHeight / (float)(imageHeight);
scale = Math.min(scaleX, scaleY);
matrix.setScale(scale, scale);
setImageMatrix(matrix);
initialScale = 1f;
// Center the image
unusedHeight = (float) imageViewHeight - (scale * (float) imageHeight) ;
unusedWidth = (float) imageViewWidth - (scale * (float) imageWidth);
unusedHeight /= (float)2;
unusedWidth /= (float)2;
matrix.postTranslate(unusedWidth, unusedHeight);
origWidth = imageViewWidth - 2 * unusedWidth;
origHeight = imageViewHeight - 2 * unusedHeight;
right = imageViewWidth * initialScale - imageViewWidth - (2 * unusedWidth * initialScale);
bottom = imageViewHeight * initialScale - imageViewHeight - (2 * unusedHeight * initialScale);
setImageMatrix(matrix);
}
class DoubleTapPinchZoomListener implements OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {
mScaleDetector.onTouchEvent(event);
mDetector.onTouchEvent(event);
matrix.getValues(floatArray);
float x = floatArray[Matrix.MTRANS_X];
float y = floatArray[Matrix.MTRANS_Y];
PointF curr = new PointF(event.getX(), event.getY());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
last.set(event.getX(), event.getY());
start.set(last);
mode = DRAG;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
float scaleWidth = Math.round(origWidth * initialScale);
float scaleHeight = Math.round(origHeight * initialScale);
if (scaleWidth < imageViewWidth) {
deltaX = 0;
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
} else if (scaleHeight < imageViewHeight) {
deltaY = 0;
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
} else {
if (x + deltaX > 0)
deltaX = -x;
else if (x + deltaX < -right)
deltaX = -(x + right);
if (y + deltaY > 0)
deltaY = -y;
else if (y + deltaY < -bottom)
deltaY = -(y + bottom);
}
matrix.postTranslate(deltaX, deltaY);
last.set(curr.x, curr.y);
}
break;
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
}
setImageMatrix(matrix);
invalidate();
return true;
}
}
}
答案 0 :(得分:1)
事实证明这个问题与MATRIX缩放无关,尽管这对我来说仍然有些神秘。问题是“自动化”重新缩放。我把我的图像放在'drawable'文件夹中,Android会自动缩放到'最适合屏幕大小'。有关这方面的更多信息,请参见此处:
http://developer.android.com/guide/practices/screens_support.html#support
解决方案是将图像放入drawable-nodpi中。这告诉Android NOT根据屏幕大小重新缩放,因此,手动操纵缩放不会与Android自身的缩放冲突。