2010-07-20 9 views
6

Ich würde gerne die gleiche Art von App wie Gallery3D neu erstellen, aber einfacher: ohne die 3D-Animationen und grundsätzlich nur GridView und Galerie Widgets. Ich möchte auch Multitouch-Zooming-Drag-Scolling auf dem ausgewählten Bild aktivieren und das ist, wo ich kämpfe. Ich schaute online nach einfachen Tutorials und ich schaute mir auch den Source Code von Gallery3D an, konnte aber keine passende Lösung finden.Android Gallery Adapter mit MultiTouch? Benutzerdefinierte Galerie oder benutzerdefinierte ImageView?

Das nächste, was ich bekommen konnte, war die Verwendung der benutzerdefinierten ImageView unten in meinem Gallery Adapter.

Es funktioniert, ich kann Pinch-and-Zoom und ziehen, außer dass das Bild vom Bildschirm verschwindet und ich kann nicht zum nächsten Bild in der Galerie scrollen. Auch Pinch-and-Zoom ist nicht perfekt, da es nur das Bild skaliert und es nicht richtig zentriert. Sollte ich stattdessen ein onTouchEvent in der Galerie hinzufügen?


import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.drawable.BitmapDrawable; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.ScaleGestureDetector; 
import android.view.View; 

public class MyImageView extends View { 

private static final int INVALID_POINTER_ID = -1; 

    private BitmapDrawable mImage; 
    private float mPosX; 
    private float mPosY; 

    private float mLastTouchX; 
    private float mLastTouchY; 
    private int mActivePointerId = INVALID_POINTER_ID; 

    private ScaleGestureDetector mScaleDetector; 
    private float mScaleFactor = 1.f; 

    public MyImageView(Context context, BitmapDrawable bd) { 
     this(context, null, 0); 
    mImage = bd; 
     mImage.setBounds(0, 0, mImage.getIntrinsicWidth(), mImage.getIntrinsicHeight()); 
    } 

    public MyImageView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public MyImageView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
    } 

    @Override 
    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; 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     canvas.save(); 
     Log.d("DEBUG", "X: "+mPosX+" Y: "+mPosY); 
     canvas.translate(mPosX, mPosY); 
     canvas.scale(mScaleFactor, mScaleFactor); 
     mImage.draw(canvas); 
     canvas.restore(); 
    } 

    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, 10.0f)); 

      invalidate(); 
      return true; 
     } 
    } 

} 

Dank

Antwort

Verwandte Themen