我编写了一个可以拖动图像的 android 应用程序。默认模式下图像的顶部和左侧是 0, 0。我的问题是如何在拖动后获得可见图像的顶部和左侧。
触摸类:
public class Touch implements OnTouchListener {
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private static final float MIN_ZOOM = 1f;
private static final float MAX_ZOOM = 5f;
private Matrix matrix = new Matrix();
private Matrix savedMatrix = new Matrix();
private PointF start = new PointF();
private PointF mid = new PointF();
private float[] values = new float[9];
private int mode = NONE;
private float dx;
private float dy;
private float matrixX = 0;
private float matrixY = 0;
private float width = 0;
private float height = 0;
private float oldDistance = 1f;
public boolean onTouch(View view, MotionEvent event) {
ImageView imageView = (ImageView)view;
switch(event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDistance = spacing(event);
if(oldDistance > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if(mode == DRAG) {
matrix.set(savedMatrix);
matrix.getValues(values);
matrixX = values[Matrix.MTRANS_X];
matrixY = values[Matrix.MTRANS_Y];
width = values[Matrix.MSCALE_X] * imageView.getDrawable().getIntrinsicWidth();
height = values[Matrix.MSCALE_Y] * imageView.getDrawable().getIntrinsicHeight();
dx = event.getX() - start.x;
dy = event.getY() - start.y;
if(matrixY + dy > 0)
while(matrixY + dy > 0)
dy--;
if(matrixX + dx + width < imageView.getWidth())
while(matrixX + dx + width < imageView.getWidth())
dx++;
if(matrixY + dy + height < imageView.getHeight())
while(matrixY + dy + height < imageView.getHeight())
dy++;
if(matrixX + dx > 0)
while(matrixX + dx > 0)
dx--;
matrix.postTranslate(dx, dy);
}
else if(mode == ZOOM) {
float newDistance = spacing(event);
if(newDistance > 10f) {
matrix.set(savedMatrix);
float scale = newDistance / oldDistance;
matrix.getValues(values);
float currentScale = values[Matrix.MSCALE_X];
if(scale * currentScale > MAX_ZOOM)
scale = MAX_ZOOM / currentScale;
else if (scale * currentScale < MIN_ZOOM)
scale = MIN_ZOOM / currentScale;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
imageView.setImageMatrix(matrix);
return true;
}
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 void midPoint(PointF point, MotionEvent event) {
point.set((event.getX(0) + event.getX(1)) / 2, (event.getY(0) + event.getY(1)) / 2);
}
}
活动类:
public class RepositionTestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.reposition_test_layout);
imageView = (ImageView)findViewById(R.id.android_image);
imageView.setOnTouchListener(new Touch());
}
}
布局xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/reposition_test_layout"
android:paddingLeft="20dp"
android:paddingTop="20dp"
android:paddingRight="20dp"
android:paddingBottom="20dp"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="@+id/android_image"
android:src="@drawable/android"
android:layout_width="300dp"
android:layout_height="300dp"
android:scaleType="matrix"
android:contentDescription="@string/android_image_description" >
</ImageView>
</LinearLayout>
谢谢你的帮助。