У меня немного замешательство с canvas
в андроиде, и мне было интересно, может ли кто-нибудь прояснить некоторые вещи для меня.Android - путаница на холсте (рисование и прокрутка)
настоящее время у меня этот код в моем классе View:
class HomerView extends View { // the custom View for drawing on
// set up Bitmap, canvas, path and paint
private Bitmap myBitmap; // the initial image we turn into our canvas
private Canvas myCanvas; // the canvas we are drawing on
private Rect myRect; // the mathematical path of the lines we draw
private Paint myBitmapPaint; // the paint we use to draw the bitmap
// get the width of the entire tablet screen
private int screenWidth = getContext().getResources()
.getDisplayMetrics().widthPixels;
// get the height of the entire tablet screen
private int screenHeight = getContext().getResources()
.getDisplayMetrics().heightPixels;
private int mX, mY, iX, iY; // current x,y and initial x,y
private static final float TOUCH_TOLERANCE = 4;
private static final int INVALID_POINTER_ID = -1;
private float mPosX;
private float mPosY;
private BitmapDrawable mImage;
private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId = INVALID_POINTER_ID;
private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;
public HomerView(Context context) { // constructor of HomerView
super(context);
myBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
Bitmap.Config.ARGB_8888); // set our drawable space - the bitmap which becomes the canvas we draw on
myCanvas = new Canvas(myBitmap); // set our canvas to our bitmap which we just set up
myRect = new Rect(); // make a new rect
myBitmapPaint = new Paint(Paint.DITHER_FLAG); // set dither to ON in our saved drawing - gives better color interaction
setHorizontalScrollBarEnabled(true);
setVerticalScrollBarEnabled(true);
TypedArray a = context.obtainStyledAttributes(R.styleable.View);
initializeScrollbars(a);
a.recycle();
computeVerticalScrollRange();
computeHorizontalScrollRange();
mImage = new BitmapDrawable(getResources(), myBitmap);
mScaleDetector = new ScaleGestureDetector(context,
new ScaleListener());
}
public HomerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScaleDetector = new ScaleGestureDetector(context,
new ScaleListener());
}
public HomerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
protected void onDraw(Canvas canvas) { // method used when we want to draw something to our canvas
super.onDraw(canvas);
if (addObjectMode == true) {
canvas.drawColor(Color.TRANSPARENT); // sets canvas colour
canvas.drawBitmap(myBitmap, 0, 0, myBitmapPaint); // save the canvas to bitmap - the numbers are the x, y coords we are drawing from
canvas.drawRect(myRect, myPaint); // draw the rectangle that the user has drawn using the paint we set up
} else if (moveMode == true) {
canvas.save();
System.out.println("X: " + mPosX + " Y: " + mPosY);
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
mImage.draw(canvas);
canvas.restore();
}
Это своего рода объединение 2-х различных подходов к рисования на экране, как я понимаю. Я понимаю, что у меня есть myBitmap
(это то, на что рисуются чертежи пользователей), и это отлично работает для «addObjectMode». Тем не менее, «moveMode» - это когда я хочу, чтобы пользователи могли зажимать прокрутку и т. Д. Вокруг плана дома, который они нарисовали.
В настоящее время я могу нарисовать объекты в порядке, но когда я нажимаю кнопку, чтобы включить moveMode
, рисунок исчезает, когда я касаюсь или жест. Я знаю, что это, вероятно, из-за кода в onDraw()
; но холсты все еще немного загадочны для меня.
В конце концов, мне понадобится базовая функция отмены/повтора, а также сохранение canvas/bitmap
, который будет открыт позже. Может ли кто-нибудь предлагать какие-либо советы или ссылки на любые всеобъемлющие учебники по холсту?
EDIT: это может быть полезно включить мои onTouchEvent
методы слишком-
public boolean onTouchEvent(MotionEvent event) { // on any touch event
if (addObjectMode == true) {
float x = event.getX(); // get current X
float y = event.getY(); // get current Y
switch (event.getAction()) { // what action is the user performing?
case MotionEvent.ACTION_DOWN: // if user is touching down
touch_Start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE: // if user is moving finger while touched down
touch_Move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP: // if user has released finger
touch_Up();
invalidate();
break;
}
return true;
} else if (moveMode == true) {
mScaleDetector.onTouchEvent(event);
final int action = event.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
final float x = event.getX();
final float y = event.getY();
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = event.getPointerId(0);
break;
}
case MotionEvent.ACTION_MOVE: {
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;
}
}
return true;
} else {
return false;
}
}
А ... не строка 'mImage.draw (canvas);' рисовать на холст? Вместо этого добавлено '\t \t \t \t canvas.drawBitmap (myBitmap, 0, 0, myBitmapPaint);' before canvas.restore(); Это работает, хотя, когда я затем зажимаю зум и переключаюсь в режим рисования, он сразу возвращается к исходному уровню масштабирования, как если бы прокрутки не было. Любая идея почему? –
Да, так же, как ваш рисунок не применим к вашему movemode, ваши преобразования перевода не применяются к вашему drawMode здесь;) – Guian
Я предлагаю вам выделить механизм перемещения/рисования из метода рисования, нарисовать его на уникальный вывод растрового изображения для пользовательских событий. то по методу onDraw выведите только растровое изображение вывода. – Guian