我正在绘制位图并尝试使用 Canvas 对其进行一些绘制。对于绘图,每当用户在其表面上绘制某些东西时,我都会添加路径。我已经在位图上实现了捏缩放和拖动功能,但是当用户缩放位图并在其上绘制一些东西时,路径无法正确绘制。我正在使用 Matrix 进行缩放和拖动功能。我的问题是使用带有矩阵的路径。
问问题
2487 次
1 回答
1
This is a working example where you can see how to implement a draggable and zoomable Path:
MainActivity
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class DrawActivity extends Activity {
DrawView drawView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set full screen view
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
drawView = new DrawView(DrawActivity.this);
setContentView(drawView);
}
}
DrawView
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.WindowManager;
public class DrawView extends View {
Context ctx;
static final String TAG = "DrawView";
Paint paint = new Paint();
//These two constants specify the minimum and maximum zoom
private static float MIN_ZOOM = 3f;
private static float MAX_ZOOM = 10f;
private float scaleFactor = 3.f;
private ScaleGestureDetector detector;
//These two variables keep track of the X and Y coordinate of the finger when it first
//touches the screen
private float startX = 0f;
private float startY = 0f;
//These two variables keep track of the amount we need to translate the canvas along the X
//and the Y coordinate
private float translateX = 0f;
private float translateY = 0f;
//These two variables keep track of the amount we translated the X and Y coordinates, the last time we
//panned.
private float previousTranslateX = 0f;
private float previousTranslateY = 0f;
private boolean dragged = false;
// Used for set first translate to a quarter of screen
private float displayWidth;
private float displayHeight;
public DrawView(Context context)
{
super(context);
ctx = context;
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
displayWidth = metrics.widthPixels;
displayHeight = metrics.heightPixels;
translateX = displayWidth/4;
translateY = displayHeight/4;
previousTranslateX = displayWidth/4;
previousTranslateY = displayHeight/4;
detector = new ScaleGestureDetector(context, new ScaleListener());
setFocusable(true);
setFocusableInTouchMode(true);
// Path's color
paint.setColor(Color.GRAY);
paint.setAntiAlias(false);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
//We're going to scale the X and Y coordinates by the same amount
canvas.scale(scaleFactor, scaleFactor, 0, 0);
//We need to divide by the scale factor here, otherwise we end up with excessive panning based on our zoom level
//because the translation amount also gets scaled according to how much we've zoomed into the canvas.
canvas.translate((translateX) / scaleFactor, (translateY) / scaleFactor);
canvas.drawRect(0, 0, 100, 100, paint);
canvas.restore();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// First finger is on screen
//We assign the current X and Y coordinate of the finger to startX and startY minus the previously translated
//amount for each coordinates This works even when we are translating the first time because the initial
//values for these two variables is zero.
startX = event.getX() - previousTranslateX;
startY = event.getY() - previousTranslateY;
break;
case MotionEvent.ACTION_MOVE:
// first finger is moving on screen
// update translation value to apply on Path
translateX = event.getX() - startX;
translateY = event.getY() - startY;
break;
case MotionEvent.ACTION_UP:
// No more fingers on screen
// All fingers went up, so let's save the value of translateX and translateY into previousTranslateX and
//previousTranslate
previousTranslateX = translateX;
previousTranslateY = translateY;
break;
// All touch events are sended to ScaleListener
detector.onTouchEvent(event);
return true;
}
class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
scaleFactor *= detector.getScaleFactor();
scaleFactor = Math.max(MIN_ZOOM, Math.min(scaleFactor, MAX_ZOOM));
invalidate();
return true;
}
}
}
于 2013-03-06T16:10:44.637 回答