2013-06-24 3 views
1

Я пытаюсь реализовать двойной кран и щепотку для увеличения активности. Я написал код для первого, но он, похоже, не работает (теперь я могу использовать только эмулятор android для eclipse. Поэтому я не уверен, что мой результат правильный)Активность масштабирования изображения для android

В любом случае я не способный понять, что я делаю неправильно. Я, конечно, что-то забываю.

Это мой код:

public class ImageZoomView extends View implements OnGestureListener { 

private static final int SCALING_FACTOR = 50; 
private final int LANDSCAPE = 1; 
private GestureDetector gestureDetector; 
private Drawable image = null; 
private int scalefactor = 0; 
private int orientation; 
private int zoomCtr = 0; 
private long lastTouchTime = 0; 
private int winX, winY, imageX, imageY, scrollX = 0, scrollY = 0, left, 
top, bottom, right; 

public ImageZoomView(Context context, int orientation) { 
      super(context); 
      setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 
        LayoutParams.FILL_PARENT)); 
      this.orientation = orientation; 
      gestureDetector = new GestureDetector(this); 
     } 

    public void setImage(Drawable bitmap, Activity activity) { 
     image = bitmap; 
     imageSetting(activity); 
    } 

    public void setImage(Bitmap bitmap, Activity activity) { 
     image = new BitmapDrawable(bitmap).getCurrent(); 
     imageSetting(activity); 
    } 

    /** 
    * Works in both landscape and portrait mode. 
    */ 
    private void imageSetting(Activity activity) { 
     scrollX = scrollY = 0; 
     scalefactor = 0; 
     imageX = winX = activity.getWindow().getWindowManager() 
       .getDefaultDisplay().getWidth(); 
     imageY = winY = activity.getWindow().getWindowManager() 
       .getDefaultDisplay().getHeight(); 
     if (orientation == LANDSCAPE) { 
      imageX = 3 * imageY/4; 
     } 
     calculatePos(); 
    } 

    public void calculatePos() { 
     int tempx, tempy; 
     tempx = imageX + imageX * scalefactor/100; 
     tempy = imageY + imageY * scalefactor/100; 
     left = (winX - tempx)/2; 
     top = (winY - tempy)/2; 
     right = (winX + tempx)/2; 
     bottom = (winY + tempy)/2; 
     invalidate(); 
    } 

    /** 
    * Redraws the bitmap when zoomed or scrolled. 
    */ 
    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     if (image == null) 
      return; 

     image.setBounds(left + scrollX, top + scrollY, right + scrollX, bottom 
       + scrollY); 
     image.draw(canvas); 
    } 

    public void zoomIn() { 
     scalefactor += SCALING_FACTOR; 
     calculatePos(); 
    } 

    public void zoomOut() { 
     if (scalefactor == 0) 
      return; 
     scrollX = scrollY = 0; 
     scalefactor -= SCALING_FACTOR; 
     calculatePos(); 
    } 

    public void scroll(int x, int y) { 
     scrollX += x/5; 
     scrollY += y/5; 
     if (scrollX + left > 0) { 
      scrollX = 0 - left; 
     } else if (scrollX + right < winX) { 
      scrollX = winX - right; 
     } 
     if (scrollY + top > 0) { 
      scrollY = 0 - top; 
     } else if (scrollY + bottom < winY) { 
      scrollY = winY - bottom; 
     } 
     invalidate(); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent me) { 
     boolean onTouchEvent = gestureDetector.onTouchEvent(me); 
     return onTouchEvent; 
    } 

    @Override 
    public boolean onDown(MotionEvent arg0) { 
     long thisTime = arg0.getEventTime(); 
     if (thisTime - lastTouchTime < 250) { 
      lastTouchTime = -1; 
      onDoubleTap(); 
      return true; 
     } 
     lastTouchTime = thisTime; 
     return true; 
    } 

    @Override 
     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, 
       float distanceY) { 
      if (zoomCtr == 0) 
       return false; 
      scroll((int) (e2.getX() - e1.getX()), (int) (e2.getY() - e1.getY())); 
      return true; 
     } 

     private void onDoubleTap() { 
      if (zoomCtr == 0) { 
       zoomCtr++; 
       zoomIn(); 
       return; 
      } 
      zoomCtr--; 
      zoomOut(); 
    } 
} 

И это, где я называю активность:

public class FullScreenPhoto extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_full_screen_photo); 
    Intent intent = getIntent(); 
    String path = intent.getStringExtra("Path"); 
    ImageView img = (ImageView)findViewById(R.id.photo); 
    img.setImageURI(Uri.parse(path)); 

    ImageZoomView imageView = new ImageZoomView(
      this,getWindow().getWindowManager().getDefaultDisplay().getOrientation()); 
    this.setContentView(imageView); 
    } 
} 

Он отображает полное изображение на экране, но когда нажав на него, ничего не происходит.

+0

Вы согласны с использованием полного кода. Я использую этот код ежедневно. Похожие на ваш. легко реализовать – MDMalik

+0

Конечно, я, если это может помочь в достижении моей цели :) – Igr

ответ

3

Великий создать класс под названием ZoomFunctionality

ZoomFunctionality

package com.androidhive.work; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Matrix; 
import android.graphics.PointF; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.ScaleGestureDetector; 
import android.view.View; 
import android.widget.ImageView; 

public class ZoomFunctionality extends ImageView { 
Matrix matrix = new Matrix(); 

// We can be in one of these 3 states 
static final int NONE = 0; 
static final int DRAG = 1; 
static final int ZOOM = 2; 
int mode = NONE; 

// Remember some things for zooming 
PointF last = new PointF(); 
PointF start = new PointF(); 
float minScale = 1f; 
float maxScale = 3f; 
float[] m; 

float redundantXSpace, redundantYSpace; 

float width, height; 
static final int CLICK = 3; 
float saveScale = 1f; 
float right, bottom, origWidth, origHeight, bmWidth, bmHeight; 

ScaleGestureDetector mScaleDetector; 

Context context; 

public ZoomFunctionality(Context context) { 
    super(context); 
    sharedConstructing(context); 
} 

public ZoomFunctionality(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    sharedConstructing(context); 
} 

private void sharedConstructing(Context context) { 
    super.setClickable(true); 
    this.context = context; 
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
    matrix.setTranslate(1f, 1f); 
    m = new float[9]; 
    setImageMatrix(matrix); 
    setScaleType(ScaleType.MATRIX); 

    setOnTouchListener(new OnTouchListener() { 

     public boolean onTouch(View v, MotionEvent event) { 
      mScaleDetector.onTouchEvent(event); 

      matrix.getValues(m); 
      float x = m[Matrix.MTRANS_X]; 
      float y = m[Matrix.MTRANS_Y]; 
      PointF curr = new PointF(event.getX(), event.getY()); 

      switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       last.set(event.getX(), event.getY()); 
       start.set(last); 
       mode = DRAG; 
       break; 
      case MotionEvent.ACTION_MOVE: 
       if (mode == DRAG) { 
        float deltaX = curr.x - last.x; 
        float deltaY = curr.y - last.y; 
        float scaleWidth = Math.round(origWidth * saveScale); 
        float scaleHeight = Math.round(origHeight * saveScale); 
        if (scaleWidth < width) { 
         deltaX = 0; 
         if (y + deltaY > 0) 
          deltaY = -y; 
         else if (y + deltaY < -bottom) 
          deltaY = -(y + bottom); 
        } else if (scaleHeight < height) { 
         deltaY = 0; 
         if (x + deltaX > 0) 
          deltaX = -x; 
         else if (x + deltaX < -right) 
          deltaX = -(x + right); 
        } else { 
         if (x + deltaX > 0) 
          deltaX = -x; 
         else if (x + deltaX < -right) 
          deltaX = -(x + right); 

         if (y + deltaY > 0) 
          deltaY = -y; 
         else if (y + deltaY < -bottom) 
          deltaY = -(y + bottom); 
        } 
        matrix.postTranslate(deltaX, deltaY); 
        last.set(curr.x, curr.y); 
       } 
       break; 

      case MotionEvent.ACTION_UP: 
       mode = NONE; 
       int xDiff = (int) Math.abs(curr.x - start.x); 
       int yDiff = (int) Math.abs(curr.y - start.y); 
       if (xDiff < CLICK && yDiff < CLICK) 
        performClick(); 
       break; 

      case MotionEvent.ACTION_POINTER_UP: 
       mode = NONE; 
       break; 
      } 
      setImageMatrix(matrix); 
      invalidate(); 
      return true; // indicate event was handled 
     } 

    }); 
} 

@Override 
public void setImageBitmap(Bitmap bm) { 
    super.setImageBitmap(bm); 
    if (bm != null) { 
     bmWidth = bm.getWidth(); 
     bmHeight = bm.getHeight(); 
    } 
} 

public void setMaxZoom(float x) { 
    maxScale = x; 
} 

private class ScaleListener extends 
     ScaleGestureDetector.SimpleOnScaleGestureListener { 
    @Override 
    public boolean onScaleBegin(ScaleGestureDetector detector) { 
     mode = ZOOM; 
     return true; 
    } 

    @Override 
    public boolean onScale(ScaleGestureDetector detector) { 
     float mScaleFactor = detector.getScaleFactor(); 
     float origScale = saveScale; 
     saveScale *= mScaleFactor; 
     if (saveScale > maxScale) { 
      saveScale = maxScale; 
      mScaleFactor = maxScale/origScale; 
     } else if (saveScale < minScale) { 
      saveScale = minScale; 
      mScaleFactor = minScale/origScale; 
     } 
     right = width * saveScale - width 
       - (2 * redundantXSpace * saveScale); 
     bottom = height * saveScale - height 
       - (2 * redundantYSpace * saveScale); 
     if (origWidth * saveScale <= width 
       || origHeight * saveScale <= height) { 
      matrix.postScale(mScaleFactor, mScaleFactor, width/2, 
        height/2); 
      if (mScaleFactor < 1) { 
       matrix.getValues(m); 
       float x = m[Matrix.MTRANS_X]; 
       float y = m[Matrix.MTRANS_Y]; 
       if (mScaleFactor < 1) { 
        if (Math.round(origWidth * saveScale) < width) { 
         if (y < -bottom) 
          matrix.postTranslate(0, -(y + bottom)); 
         else if (y > 0) 
          matrix.postTranslate(0, -y); 
        } else { 
         if (x < -right) 
          matrix.postTranslate(-(x + right), 0); 
         else if (x > 0) 
          matrix.postTranslate(-x, 0); 
        } 
       } 
      } 
     } else { 
      matrix.postScale(mScaleFactor, mScaleFactor, 
        detector.getFocusX(), detector.getFocusY()); 
      matrix.getValues(m); 
      float x = m[Matrix.MTRANS_X]; 
      float y = m[Matrix.MTRANS_Y]; 
      if (mScaleFactor < 1) { 
       if (x < -right) 
        matrix.postTranslate(-(x + right), 0); 
       else if (x > 0) 
        matrix.postTranslate(-x, 0); 
       if (y < -bottom) 
        matrix.postTranslate(0, -(y + bottom)); 
       else if (y > 0) 
        matrix.postTranslate(0, -y); 
      } 
     } 
     return true; 

    } 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    width = MeasureSpec.getSize(widthMeasureSpec); 
    height = MeasureSpec.getSize(heightMeasureSpec); 
    // Fit to screen. 
    float scale; 
    float scaleX = (float) width/(float) bmWidth; 
    float scaleY = (float) height/(float) bmHeight; 
    scale = Math.min(scaleX, scaleY); 
    matrix.setScale(scale, scale); 
    setImageMatrix(matrix); 
    saveScale = 1f; 

    // Center the image 
    redundantYSpace = (float) height - (scale * (float) bmHeight); 
    redundantXSpace = (float) width - (scale * (float) bmWidth); 
    redundantYSpace /= (float) 2; 
    redundantXSpace /= (float) 2; 

    matrix.postTranslate(redundantXSpace, redundantYSpace); 

    origWidth = width - 2 * redundantXSpace; 
    origHeight = height - 2 * redundantYSpace; 
    right = width * saveScale - width - (2 * redundantXSpace * saveScale); 
    bottom = height * saveScale - height 
      - (2 * redundantYSpace * saveScale); 
    setImageMatrix(matrix); 
} 
} 

Теперь когда вы хотите позвонить ZoomFunctionality из вашей Activity просто написать следующее заявление

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize = 2; 
Bitmap bmp = BitmapFactory.decodeFile(filename, options); 


ZoomFunctionality img = new ZoomFunctionality(this); 
img.setImageBitmap(bmp); 
img.setMaxZoom(4f); 
setContentView(img); 

Примечание
ВМР: Является ли растровое изображение, которое вы хотите функциональность трансфокации
это: Его рекомендуется использовать Activity.this
Ее не нужно использовать BitmapFactoryOptions но декодировании из файла требуется

+0

И этот класс реализует какие жужжания? двойной кратный зум и пинч или только один из них? – Igr

+0

multitouch out и in ... я думаю, что это называется pinch ... но я не думаю, что так двойное нажатие есть – MDMalik

+0

ok Спасибо, я попробую код и сообщим вам как можно скорее – Igr

0

TouchImageView.java

package com.animation.sound; 

import android.content.Context; 
import android.graphics.Matrix; 
import android.graphics.PointF; 
import android.graphics.drawable.Drawable; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.ScaleGestureDetector; 
import android.view.View; 
import android.widget.ImageView; 

public class TouchImageView extends ImageView { 

    Matrix matrix; 

    // We can be in one of these 3 states 
    static final int NONE = 0; 
    static final int DRAG = 1; 
    static final int ZOOM = 2; 
    int mode = NONE; 

    // Remember some things for zooming 
    PointF last = new PointF(); 
    PointF start = new PointF(); 
    float minScale = 1f; 
    float maxScale = 3f; 
    float[] m; 

    int viewWidth, viewHeight; 
    static final int CLICK = 3; 
    float saveScale = 1f; 
    protected float origWidth, origHeight; 
    int oldMeasuredWidth, oldMeasuredHeight; 

    ScaleGestureDetector mScaleDetector; 

    Context context; 

    public TouchImageView(Context context) { 
     super(context); 
     sharedConstructing(context); 
    } 

    public TouchImageView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     sharedConstructing(context); 
    } 

    private void sharedConstructing(Context context) { 
     super.setClickable(true); 
     this.context = context; 
     mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
     matrix = new Matrix(); 
     m = new float[9]; 
     setImageMatrix(matrix); 
     setScaleType(ScaleType.MATRIX); 

     setOnTouchListener(new OnTouchListener() { 

      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       mScaleDetector.onTouchEvent(event); 
       PointF curr = new PointF(event.getX(), event.getY()); 

       switch (event.getAction()) { 
       case MotionEvent.ACTION_DOWN: 
        last.set(curr); 
        start.set(last); 
        mode = DRAG; 
        break; 

       case MotionEvent.ACTION_MOVE: 
        if (mode == DRAG) { 
         float deltaX = curr.x - last.x; 
         float deltaY = curr.y - last.y; 
         float fixTransX = getFixDragTrans(deltaX, viewWidth, 
           origWidth * saveScale); 
         float fixTransY = getFixDragTrans(deltaY, viewHeight, 
           origHeight * saveScale); 
         matrix.postTranslate(fixTransX, fixTransY); 
         fixTrans(); 
         last.set(curr.x, curr.y); 
        } 
        break; 

       case MotionEvent.ACTION_UP: 
        mode = NONE; 
        int xDiff = (int) Math.abs(curr.x - start.x); 
        int yDiff = (int) Math.abs(curr.y - start.y); 
        if (xDiff < CLICK && yDiff < CLICK) 
         performClick(); 
        break; 

       case MotionEvent.ACTION_POINTER_UP: 
        mode = NONE; 
        break; 
       } 

       setImageMatrix(matrix); 
       invalidate(); 
       return true; // indicate event was handled 
      } 

     }); 
    } 

    public void setMaxZoom(float x) { 
     maxScale = x; 
    } 

    private class ScaleListener extends 
      ScaleGestureDetector.SimpleOnScaleGestureListener { 
     @Override 
     public boolean onScaleBegin(ScaleGestureDetector detector) { 
      mode = ZOOM; 
      return true; 
     } 

     @Override 
     public boolean onScale(ScaleGestureDetector detector) { 
      float mScaleFactor = detector.getScaleFactor(); 
      float origScale = saveScale; 
      saveScale *= mScaleFactor; 
      if (saveScale > maxScale) { 
       saveScale = maxScale; 
       mScaleFactor = maxScale/origScale; 
      } else if (saveScale < minScale) { 
       saveScale = minScale; 
       mScaleFactor = minScale/origScale; 
      } 

      if (origWidth * saveScale <= viewWidth 
        || origHeight * saveScale <= viewHeight) 
       matrix.postScale(mScaleFactor, mScaleFactor, viewWidth/2, 
         viewHeight/2); 
      else 
       matrix.postScale(mScaleFactor, mScaleFactor, 
         detector.getFocusX(), detector.getFocusY()); 

      fixTrans(); 
      return true; 
     } 
    } 

    void fixTrans() { 
     matrix.getValues(m); 
     float transX = m[Matrix.MTRANS_X]; 
     float transY = m[Matrix.MTRANS_Y]; 

     float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale); 
     float fixTransY = getFixTrans(transY, viewHeight, origHeight 
       * saveScale); 

     if (fixTransX != 0 || fixTransY != 0) 
      matrix.postTranslate(fixTransX, fixTransY); 
    } 

    float getFixTrans(float trans, float viewSize, float contentSize) { 
     float minTrans, maxTrans; 

     if (contentSize <= viewSize) { 
      minTrans = 0; 
      maxTrans = viewSize - contentSize; 
     } else { 
      minTrans = viewSize - contentSize; 
      maxTrans = 0; 
     } 

     if (trans < minTrans) 
      return -trans + minTrans; 
     if (trans > maxTrans) 
      return -trans + maxTrans; 
     return 0; 
    } 

    float getFixDragTrans(float delta, float viewSize, float contentSize) { 
     if (contentSize <= viewSize) { 
      return 0; 
     } 
     return delta; 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
     viewWidth = MeasureSpec.getSize(widthMeasureSpec); 
     viewHeight = MeasureSpec.getSize(heightMeasureSpec); 

     // 
     // Rescales image on rotation 
     // 
     if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight 
       || viewWidth == 0 || viewHeight == 0) 
      return; 
     oldMeasuredHeight = viewHeight; 
     oldMeasuredWidth = viewWidth; 

     if (saveScale == 1) { 
      // Fit to screen. 
      float scale; 

      Drawable drawable = getDrawable(); 
      if (drawable == null || drawable.getIntrinsicWidth() == 0 
        || drawable.getIntrinsicHeight() == 0) 
       return; 
      int bmWidth = drawable.getIntrinsicWidth(); 
      int bmHeight = drawable.getIntrinsicHeight(); 

      Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight); 

      float scaleX = (float) viewWidth/(float) bmWidth; 
      float scaleY = (float) viewHeight/(float) bmHeight; 
      scale = Math.min(scaleX, scaleY); 
      matrix.setScale(scale, scale); 

      // Center the image 
      float redundantYSpace = (float) viewHeight 
        - (scale * (float) bmHeight); 
      float redundantXSpace = (float) viewWidth 
        - (scale * (float) bmWidth); 
      redundantYSpace /= (float) 2; 
      redundantXSpace /= (float) 2; 

      matrix.postTranslate(redundantXSpace, redundantYSpace); 

      origWidth = viewWidth - 2 * redundantXSpace; 
      origHeight = viewHeight - 2 * redundantYSpace; 
      setImageMatrix(matrix); 
     } 
     fixTrans(); 
    } 
} 

поставить это строки в классе MainActivity.java ...

TouchImageView imgView; 
imgView = (TouchImageView) findViewById(R.id.imgmstlv); 

И дополнительная информация. Следуйте по этой ссылке Zoom In & Zoom out