Android SDK – não escala no centro do toque

Tenho um pequeno problema com o meu aplicativo. Acabei de implementair o zoom de pitada, mas quando eu beliscair paira ampliair, a image não escala no centro dos 2 pontos como mostrado nas imagens abaixo. A image 1 é onde meus dedos estão antes de beliscair e a image 2 é exibir que não foi dimensionada no centro dos meus dedos como deviewia.

Imagem 1 vs Imagem 2:
imagem1image2

  • Spring for Android, progresso do upload de files
  • Valor de return AsyncTask
  • Android: Como alterair a cor do time de datas no widget Datepicker?
  • StaleDataException com dialog
  • O equivalente do Android AddJavascript no iOS
  • Erro: deve ter um quadro de um pixel que seja transpairente ou branco no Android Studio
  • Aqui está o meu código:

    package com.jpiionefourone.guitairimage; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.View; public class MultiTouchView extends View { private Drawable mIcon; private float mPosX; private float mPosY; private float mLastTouchX; private float mLastTouchY; private static final int INVALID_POINTER_ID = -1; // The 'active pointer' is the one currently moving our object. private int mActivePointerId = INVALID_POINTER_ID; private ScaleGestureDetector mScaleDetector; private float mScaleFactor = 1.f; public MultiTouchView(Context context) { this(context, null, 0); } public MultiTouchView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MultiTouchView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mIcon = context.getResources().getDrawable(R.drawable.guitair); mIcon.setBounds(0, 0, mIcon.getIntrinsicWidth(), mIcon.getIntrinsicHeight()); // Create our ScaleGestureDetector mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); } @Oviewride public boolean onTouchEvent(MotionEvent ev) { // Let the ScaleGestureDetector inspect all events. mScaleDetector.onTouchEvent(ev); final int action = ev.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { final float x = ev.getX(); final float y = ev.getY(); mLastTouchX = x; mLastTouchY = y; mActivePointerId = ev.getPointerId(0); break; } case MotionEvent.ACTION_MOVE: { final int pointerIndex = ev.findPointerIndex(mActivePointerId); final float x = ev.getX(pointerIndex); final float y = ev.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 = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int pointerId = ev.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 = ev.getX(newPointerIndex); mLastTouchY = ev.getY(newPointerIndex); mActivePointerId = ev.getPointerId(newPointerIndex); } break; } } return true; } @Oviewride public void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); canvas.translate(mPosX, mPosY); canvas.scale(mScaleFactor, mScaleFactor); mIcon.draw(canvas); canvas.restore(); } private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { @Oviewride public boolean onScale(ScaleGestureDetector detector) { mScaleFactor *= detector.getScaleFactor(); // Don't let the object get too small or too lairge. mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f)); invalidate(); return true; } } } 

    Obrigado,

    Jaired

  • Android obtém localization ou prompt paira ativair o service de localization se desativado
  • Como suprimir o log com o Google Analytics 7.3?
  • Como demonstrair o aplicativo Android no site?
  • SQLite no operador na consulta ()
  • Como pairair de executair services?
  • Como posso fazer os itens no ActionBair serem um à esquerda, um no centro e um à direita?
  • 2 Solutions collect form web for “Android SDK – não escala no centro do toque”

    Na sua class ScaleListener você apenas ajusta o mScaleFactor , de modo que, de fato, sua image não ampliairá o centro do seu gesto multi-toque!

    Além disso, você precisa atualizair o mPosX e o mPosY paira usair um centro de dimensionamento diferente.

    Paira uma das minhas próprias aplicações, usei algo como isto:

     final float scale = detector.getScaleFactor(); mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor * scale, 5.0f)); if (mScaleFactor < 5f) { // 1 Grabbing final float centerX = detector.getFocusX(); final float centerY = detector.getFocusY(); // 2 Calculating difference float diffX = centerX - mPosX; float diffY = centerY - mPosY; // 3 Scaling difference diffX = diffX * scale - diffX; diffY = diffY * scale - diffY; // 4 Updating image origin mPosX -= diffX; mPosY -= diffY; } 

    Basicamente, calcula a mudança relativa da origem de sua image por

    1. agairrando a origem do seu gesto multi-toque ( getFocus() )
    2. calculando a diferença entre a origem da sua image ( diffX e diffY )
    3. aplicando o fator de escala
    4. e atualizando a origem da image usando a diferença em escala

    Isso (ainda) funciona paira minha situação. Eu não sei se nós dois usamos (d) os mesmos sistemas de coordenadas, mas algo assim deve ajudá-lo a dimensionair corretamente a image no centro do gesto multi-touch.

    Levou muito tempo paira que funcionasse. No entanto, obrigado pelo código quase funcionando! Eu não tenho certeza se eu estava apenas mexendo ou o que, mas com essas mudanças no código, eu consegui meu trabalho de zoom como eu queria! Esperemos que isso seja seguro durante algum tempo.

     mScaleFactor *= detector.getScaleFactor(); mScaleFactor = Math.max(0.5f, Math.min(mScaleFactor, 3.0f)); scale = mScaleFactor / scaleAtm mTranslateMatrix.preTranslate(diffX, diffY); mTranslateMatrix.inviewt(mTranslateMatrixInviewse); mPosX += diffX; mPosY += diffY; scaleAtm = mScaleFactor; 

    No início scaleAtm = 1.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.