我有一个画布,我能够缩小并滚动边界,其代码在这里
package com.mypackage.ui.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.provider.SyncStateContract;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
*
*/
public class MyDrawingView extends View {
private static final int INVALID_POINTER_ID = -1;
private int state = 0; //0 se dibuja - 1 se mueve
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap bitmap;
protected String tool;
protected String color;
protected float brushSize;
//erase flag
private boolean erase=false;
public String getTool() {
return tool;
}
public void setTool(String tool) {
this.tool = tool;
}
public String getColor() {
return color;
}
public float getBrushSize() {
return brushSize;
}
public boolean isErase() {
return erase;
}
private String drawId;
// public OnSaveActionListener listener;
private float mPosX;
private float mPosY;
public float getMPosX() { return mPosX; }
public float getMPosY() { return mPosY; }
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
private float viewHeight;
private float viewWidth;
float canvasWidth, canvasHeight;
private float minScaleFactor;
private boolean panEnabled = true;
private boolean zoomEnabled = true;
public MyDrawingView(Context context) {
super(context);
setup();
}
public MyDrawingView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setup();
}
public MyDrawingView(Context context, AttributeSet attrs){
super(context, attrs);
setup();
}
//setup drawing
private void setup(){
mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
//prepare for drawing and setup paint stroke properties
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
public void setState(int state) {
this.state = state;
}
public void setImageBitmap(Bitmap bmp) {
bitmap = bmp;
resetZoom();
resetPan();
invalidate();
}
public void setImageDrawable(Drawable drawable) {
setImageBitmap(((BitmapDrawable) drawable).getBitmap());
}
public void setBitmap(Bitmap bmp) {
setImageBitmap(bmp);
}
public void resetZoom() {
mScaleFactor = 1.0f;
}
public void resetPan() {
mPosX = 0f;
mPosY = 0f;
}
public BitmapDrawable getImageDrawable() {
BitmapDrawable bd = new BitmapDrawable(getContext().getResources(), bitmap);
return bd;
}
public BitmapDrawable getDrawable() {
return getImageDrawable();
}
//size assigned to view
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(bitmap);
}
//draw the view - will be called after touch event
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mScaleFactor = Math.max(mScaleFactor, minScaleFactor);
canvasHeight = canvas.getHeight();
canvasWidth = canvas.getWidth();
//Save the canvas without translating (panning) or scaling (zooming)
//After each change, restore to this state, instead of compounding
//changes upon changes
canvas.save();
int maxX, minX, maxY, minY;
//Regardless of the screen density (HDPI, MDPI) or the scale factor,
//The image always consists of bitmap width divided by 2 pixels. If an image
//is 200 pixels wide and you scroll right 100 pixels, you just scrolled the image
//off the screen to the left.
minX = (int) (((viewWidth / mScaleFactor) - bitmap.getWidth()) / 2);
maxX = 0;
//How far can we move the image vertically without having a gap between image and frame?
minY = (int) (((viewHeight / mScaleFactor) - bitmap.getHeight()) / 2);
maxY = 0;
//Do not go beyond the boundaries of the image
if (mPosX > maxX) {
mPosX = maxX;
}
if (mPosX < minX) {
mPosX = minX;
}
if (mPosY > maxY) {
mPosY = maxY;
}
if (mPosY < minY) {
mPosY = minY;
}
if (state == 0) {
} else if (state == 1) {
canvas.scale(this.mScaleFactor, this.mScaleFactor, this.mScaleDetector.getFocusX(), this.mScaleDetector.getFocusY());
}
canvas.translate(mPosX, mPosY);
canvas.drawBitmap(bitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
canvas.restore();
invalidate();
}
//register user touches as drawing action
@Override
public boolean onTouchEvent(MotionEvent event) {
mScaleDetector.onTouchEvent(event);
float touchX = event.getX();
float touchY = event.getY();
if(isErase()){
drawCanvas.drawPath(drawPath, drawPaint);
invalidate();
}
//respond to down, move and up events
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastTouchX = touchX;
mLastTouchY = touchY;
mActivePointerId = event.getPointerId(0);
break;
case MotionEvent.ACTION_MOVE:
if (state == 0) {
} else if (state == 1) {
final int pointerIndex = event.findPointerIndex(mActivePointerId);
final float x = event.getX(pointerIndex);
final float y = event.getY(pointerIndex);
// Only move if the ScaleGestureDetector isn't processing a gesture.
if (!mScaleDetector.isInProgress()) {
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
}
mLastTouchX = x;
mLastTouchY = y;
}
break;
case MotionEvent.ACTION_UP:
mActivePointerId = INVALID_POINTER_ID;
break;
case MotionEvent.ACTION_CANCEL:
mActivePointerId = INVALID_POINTER_ID;
break;
case MotionEvent.ACTION_POINTER_UP:
final int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = event.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = event.getX(newPointerIndex);
mLastTouchY = event.getY(newPointerIndex);
mActivePointerId = event.getPointerId(newPointerIndex);
}
break;
default:
return false;
}
return true;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
invalidate();
return true;
}
}
}
上面的代码是一个适用于the answer here
的改编版我遇到的问题是当我放大时我无法滚动到图像的任何位置,就像角落不可更新。我知道我在界限上犯了一个错误,但我无法实现如何解决它
谢谢