Özel bir SurfaceView
uzatıyorum ve çimdik yakınlaştırma ve kaydırma yeteneğine sahip olmaya çalışıyorum. Tuvalimin çeviri matrisine sınırları nasıl yerleştirebilirim?
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// subtract scrolled amount
matrix.postTranslate(-distanceX, -distanceY);
rebound();
invalidate();
// handled
return true;
}
Ben Büyütmek Nasıl:
@Override
public boolean onScale(ScaleGestureDetector detector) {
if (detector.isInProgress()) {
// get scale
float factor = detector.getScaleFactor();
// Don't let the object get too small or too large.
if (factor * scale > 1f) {
factor = 1f/scale;
} else if (factor * scale < minScale) {
factor = minScale/scale;
}
// store local scale
scale *= factor;
// do the scale
matrix.preScale(factor, factor, detector.getFocusX(), detector.getFocusY());
rebound();
invalidate();
}
return true;
}
(referans için ben bu yöntemlerin her ikisi de anda onDraw
:)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.setMatrix(matrix);
// [...] stuff drawn with matrix settings
canvas.restore();
// [...] stuff drawn without matrix settings, as an overlay
}
için bu kodu kullanın iyi çalışıyor. Yakınlaştırma, minimum (0f ve 1f arası) ve maksimum (şu anda her zaman 1f) ölçek değeri doğru bir şekilde durdurulur. kullanılan
Küresel alanları:
drawW
,drawH
=float
, geniş ölçekte tuval veri piksel boyutu = 1parentW
, =float
parentH
, görünür bakış piksel boyutu .matrix
=android.graphics.Matrix
.
sorun "rebound()
" dir (belki daha iyi bir isme ihtiyacı var, heh) O otomatik görünümünde kalmak içeriğini zorlayacaktır uygulamak çalışılıyor yöntemi.
Sınırların nerede olması gerektiğini hesaplamak için çeşitli yöntemler denedim (dikdörtgenin içinde (0, 0, parentW, parentH)) ve çok uzağa gittiğinde matrisi "geri" çevirin.
Şu anda sahip olduğum, kesinlikle işe yaramıyor, bunun yerine sağa doğru çok daha fazla itmek. Problemin benim matematik olduğumu hissediyorum, fikrim değil. Birisi, matrisini çok uzağa çeviren ve/veya bu uygulamadaki denememle sorunları çözen daha basit veya daha temiz kodlar bulabilir mi? o üst görünmesi için kullanılan çekler
public void rebound() {
// bounds
RectF currentBounds = new RectF(0, 0, drawW, drawH);
matrix.mapRect(currentBounds);
RectF parentBounds = new RectF(0, 0, parentW, parentH/2);
PointF diff = new PointF(0, 0);
if (currentBounds.left > parentBounds.left) {
diff.x += (parentBounds.left - currentBounds.left);
}
if (currentBounds.top > parentBounds.top) {
diff.y += (parentBounds.top - currentBounds.top);
}
if (currentBounds.width() > parentBounds.width()) {
if (currentBounds.right < parentBounds.right) {
diff.x += (parentBounds.right - currentBounds.right);
}
if (currentBounds.bottom < parentBounds.bottom) {
diff.y += (parentBounds.bottom - currentBounds.bottom);
}
}
matrix.postTranslate(diff.x, diff.y);
}
matris bir alan oldu önce yazdığım bir önceki sürümü bırakılırsa çalıştı (Sadece canvas.scale()
onDraw
sonra canvas.translate()
kullanılır):
public void rebound() {
// bounds
int boundTop = 0;
int boundLeft = 0;
int boundRight = (int)(-scale * drawW + parentW);
int boundBottom = (int)(-scale * drawH + parentH);
if (boundLeft >= boundRight) {
mScrollX = Math.min(boundLeft, Math.max(boundRight, mScrollX));
} else {
mScrollX = 0;
}
if (boundTop >= boundBottom) {
mScrollY = Math.min(boundTop, Math.max(boundBottom, mScrollY));
} else {
mScrollY = 0;
}
}
Yeni yolu kullanıyorum, böylece detector.getFocusX()
, detector.getFocusY()
merkezini doğru şekilde ölçeklendirebiliyorum.
UPDATE: Yöntemi şu an için değiştirdim. Sadece biraz çalışır, hala y yönünü merkezden sınırlar ve zum seviyesini değiştirdikten sonra yanlıştır. Ayrıca "preScale" ve "postTranslate" yaptım, böylece (anladığım kadarıyla), her zaman ölçeği uyguladıktan sonra tercüme etmeli ve onları karıştırmamalı.
FINAL UPDATE: Şimdi çalışıyor.Ben geri sınırları onu çevirerek istemediğiniz herhangi kaydırma olumsuzlar
public void rebound() {
// make a rectangle representing what our current canvas looks like
RectF currentBounds = new RectF(0, 0, drawW, drawH);
matrix.mapRect(currentBounds);
// make a rectangle representing the scroll bounds
RectF areaBounds = new RectF((float) getLeft(),
(float) getTop(),
(float) parentW + (float) getLeft(),
(float) parentH + (float) getTop());
// the difference between the current rectangle and the rectangle we want
PointF diff = new PointF(0f, 0f);
// x-direction
if (currentBounds.width() > areaBounds.width()) {
// allow scrolling only if the amount of content is too wide at this scale
if (currentBounds.left > areaBounds.left) {
// stop from scrolling too far left
diff.x = (areaBounds.left - currentBounds.left);
}
if (currentBounds.right < areaBounds.right) {
// stop from scrolling too far right
diff.x = (areaBounds.right - currentBounds.right);
}
} else {
// negate any scrolling
diff.x = (areaBounds.left - currentBounds.left);
}
// y-direction
if (currentBounds.height() > areaBounds.height()) {
// allow scrolling only if the amount of content is too tall at this scale
if (currentBounds.top > areaBounds.top) {
// stop from scrolling too far above
diff.y = (areaBounds.top - currentBounds.top);
}
if (currentBounds.bottom < areaBounds.bottom) {
// stop from scrolling too far below
diff.y = (areaBounds.bottom - currentBounds.bottom);
}
} else {
// negate any scrolling
diff.y = (areaBounds.top - currentBounds.top);
}
// translate
matrix.postTranslate(diff.x, diff.y);
}
: Burada yorumlarla bir çalışma rebound
yöntemidir. İçerik çok küçükse, içeriği sol üstte olacak şekilde zorluyorsa kaydırma işlemini tamamen iptal eder.
Haklısınız! Görünüm tüm ekran boyutu değil. Tuvalin görünümü yerine matris dönüşümleri ekrana göre mi? Tabanın tuvaline değil, tuvalete göre en mantıklı olacağını varsayıyordum ... – Ribose
Matris, tuval ile göreceli, ama 0,0 konumunda sabitleniyor, böylece ölçeği iki katına çıkararak 5,5'e çekecek. 2.5.2.5 'da görünmesini sağladım Bazı durumlarda görünüm boyutunun karışık olabileceğini ve ekran boyutunu kullanacağınız gerçek görünümü değil bir kılavuz olarak kullanmayı denedim. Tuval üzerindeki nesnelerin pozisyonu için ölçeklememle birlikte tuvalin güzel oynaması için ölçeklememi almak çok fazla deneme ve hata aldı. – ScouseChris
Teşekkür ederiz! Bir sürü deneme-yanılma ile sonunda işe yaradım. – Ribose