2017-02-09 14 views
0

Я искал способ отображения очень большого прокручиваемого изображения (3700x2400) в полном размере с функциональностью ZoomIn/ZoomOut.Получить X/Y позицию щелчка внутри ImageView

Следующий вопрос дал мне прекрасное решение: Android imageView Zoom-in and Zoom-Out

package com.oryx.hanenberg; 

/** 
* Created by Jordy on 9-2-2017. 
*/ 

import android.app.Activity; 
import android.graphics.Matrix; 
import android.graphics.PointF; 
import android.os.Bundle; 
import android.util.FloatMath; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 
import android.widget.ImageView; 

public class ZoomInZoomOut extends Activity implements OnTouchListener 
{ 
    private static final String TAG = "Touch"; 
    @SuppressWarnings("unused") 
    private static final float MIN_ZOOM = 1f,MAX_ZOOM = 1f; 

    // These matrices will be used to scale points of the image 
    Matrix matrix = new Matrix(); 
    Matrix savedMatrix = new Matrix(); 

    // The 3 states (events) which the user is trying to perform 
    static final int NONE = 0; 
    static final int DRAG = 1; 
    static final int ZOOM = 2; 
    int mode = NONE; 

    // these PointF objects are used to record the point(s) the user is touching 
    PointF start = new PointF(); 
    PointF mid = new PointF(); 
    float oldDist = 1f; 

    private ImageView imageView; 
    private int fieldImgXY[] = new int[2]; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_map); 
     imageView = (ImageView) findViewById(R.id.map); 

     int[] posXY = new int[2]; 
     imageView.getLocationOnScreen(posXY); 
     int x = posXY[0]; 
     int y = posXY[1]; 

     Log.d(TAG, TAG + " " + String.valueOf(x)); 
     Log.d(TAG, TAG + " " + String.valueOf(y)); 

     imageView.setOnTouchListener(this); 
    } 

    @Override 
    public boolean onTouch(View v, MotionEvent event) 
    { 
     ImageView view = (ImageView) v; 
     view.setScaleType(ImageView.ScaleType.MATRIX); 
     float scale; 

     dumpEvent(event); 
     // Handle touch events here... 

     switch (event.getAction() & MotionEvent.ACTION_MASK) 
     { 
      case MotionEvent.ACTION_DOWN: // first finger down only 
       savedMatrix.set(matrix); 
       start.set(event.getX(), event.getY()); 
       Log.d(TAG, "mode=DRAG"); // write to LogCat 
       mode = DRAG; 
       break; 

      case MotionEvent.ACTION_UP: // first finger lifted 

       System.out.println(event.getX()); 
       System.out.println(event.getY()); 

       break; 

      case MotionEvent.ACTION_POINTER_UP: // second finger lifted 

       mode = NONE; 
       Log.d(TAG, "mode=NONE"); 
       break; 

      case MotionEvent.ACTION_POINTER_DOWN: // first and second finger down 

       oldDist = spacing(event); 
       Log.d(TAG, "oldDist=" + oldDist); 
       if (oldDist > 5f) { 
        savedMatrix.set(matrix); 
        midPoint(mid, event); 
        mode = ZOOM; 
        Log.d(TAG, "mode=ZOOM"); 
       } 
       break; 

      case MotionEvent.ACTION_MOVE: 

       if (mode == DRAG) 
       { 
        matrix.set(savedMatrix); 
        matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); // create the transformation in the matrix of points 
       } 
       else if (mode == ZOOM) 
       { 
        // pinch zooming 
        float newDist = spacing(event); 
        Log.d(TAG, "newDist=" + newDist); 
        if (newDist > 5f) 
        { 
         matrix.set(savedMatrix); 
         scale = newDist/oldDist; // setting the scaling of the 
         // matrix...if scale > 1 means 
         // zoom in...if scale < 1 means 
         // zoom out 
         matrix.postScale(scale, scale, mid.x, mid.y); 
        } 
       } 
       break; 
     } 

     view.setImageMatrix(matrix); // display the transformation on screen 

     return true; // indicate event was handled 
    } 

    /* 
    * -------------------------------------------------------------------------- 
    * Method: spacing Parameters: MotionEvent Returns: float Description: 
    * checks the spacing between the two fingers on touch 
    * ---------------------------------------------------- 
    */ 

    private float spacing(MotionEvent event) 
    { 
     float x = event.getX(0) - event.getX(1); 
     float y = event.getY(0) - event.getY(1); 
     return (float) Math.sqrt(x * x + y * y); 
    } 

    /* 
    * -------------------------------------------------------------------------- 
    * Method: midPoint Parameters: PointF object, MotionEvent Returns: void 
    * Description: calculates the midpoint between the two fingers 
    * ------------------------------------------------------------ 
    */ 

    private void midPoint(PointF point, MotionEvent event) 
    { 
     float x = event.getX(0) + event.getX(1); 
     float y = event.getY(0) + event.getY(1); 
     point.set(x/2, y/2); 
    } 

    /** Show an event in the LogCat view, for debugging */ 
    private void dumpEvent(MotionEvent event) 
    { 
     String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE","POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" }; 
     StringBuilder sb = new StringBuilder(); 
     int action = event.getAction(); 
     int actionCode = action & MotionEvent.ACTION_MASK; 
     sb.append("event ACTION_").append(names[actionCode]); 

     if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) 
     { 
      sb.append("(pid ").append(action >> MotionEvent.ACTION_POINTER_ID_SHIFT); 
      sb.append(")"); 
     } 

     sb.append("["); 
     for (int i = 0; i < event.getPointerCount(); i++) 
     { 
      sb.append("#").append(i); 
      sb.append("(pid ").append(event.getPointerId(i)); 
      sb.append(")=").append((int) event.getX(i)); 
      sb.append(",").append((int) event.getY(i)); 
      if (i + 1 < event.getPointerCount()) 
       sb.append(";"); 
     } 

     sb.append("]"); 
     Log.d("Touch Events ---------", sb.toString()); 
    } 
} 

activity_map.xml

<LinearLayout android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_gravity = "center_vertical|center_horizontal|center" 
    android:layout_weight="1" 
    > 

    <ImageView 
     android:id="@+id/map" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@drawable/bt_587f3ef7ccafa_bt_origineel"/> 

</LinearLayout> 

Однако я хочу прикосновений события зарегистрировать X/Y-координаты относительно образ. Теперь он создает пробел вокруг изображения, когда я увеличиваю масштабные ложные X/Y-координаты. Координаты X/Y также относятся к окну просмотра, а не ко всему содержимому. Как я могу это сделать?

ответ

2

Вы можете получить верхний левый угол ImageView, как указано ниже:

int[] posXY = new int[2]; 
imageView.getLocationOnScreen(posXY); 

С этим и сенсорный координаты можно вычислить точку внутри ImageView следующим образом:

int touchX = (int) event.getX(); 
int touchY = (int) event.getY(); 

int imageX = touchX - posXY[0]; // posXY[0] is the X coordinate 
int imageY = touchY - posXY[1]; // posXY[1] is the y coordinate 
+0

Хммм I уже пробовал этот путь, но я все еще получаю только координаты X/Y внутри окна просмотра. Верхний левый угол также не равен 0. – Jordy

+0

Опубликовать значения posXY – Athul

+0

перекрестно проверить эти значения @Jordy – Athul

 Смежные вопросы

  • Нет связанных вопросов^_^