Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
android imageView:设置拖动和收缩缩放参数_Android_Drag And Drop_Imageview_Zooming_Pinch - Fatal编程技术网

android imageView:设置拖动和收缩缩放参数

android imageView:设置拖动和收缩缩放参数,android,drag-and-drop,imageview,zooming,pinch,Android,Drag And Drop,Imageview,Zooming,Pinch,我目前正在为Android(我的第一个应用程序)开发一个应用程序,它可以让用户看到地铁地图,并能够进行缩放和拖动 我目前正在修改Hello Android第三版中的代码,并通过缩放和拖动来工作。我使用矩阵作为我的布局比例 但我现在有3个问题: 我尝试了很多方法来限制拖动参数,但我似乎无法阻止它从父视图中被拖动(实际上可以从视图中消失)。我试着在XML文件中设置布局参数,但它就是不起作用 我可以很好地收缩缩放,但我有麻烦,再次限制缩放量。我正在尝试设置最大缩放和最小缩放来限制缩放值(之后我会发布代

我目前正在为Android(我的第一个应用程序)开发一个应用程序,它可以让用户看到地铁地图,并能够进行缩放和拖动

我目前正在修改Hello Android第三版中的代码,并通过缩放和拖动来工作。我使用矩阵作为我的布局比例

但我现在有3个问题:

  • 我尝试了很多方法来限制拖动参数,但我似乎无法阻止它从父视图中被拖动(实际上可以从视图中消失)。我试着在XML文件中设置布局参数,但它就是不起作用

  • 我可以很好地收缩缩放,但我有麻烦,再次限制缩放量。我正在尝试设置最大缩放和最小缩放来限制缩放值(之后我会发布代码)

  • 我在尝试在我的图像上绘制坐标时也遇到了问题,这样人们就可以点击某些部分(其目的是让用户点击地图上的一个站点并查看其相关信息)

  • 我有一种感觉,我有麻烦,因为我在使用矩阵尺度

    这是我目前的代码:

    Touch.java

    package org.example.touch;
    import android.app.Activity;
    import android.graphics.Bitmap;
    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.GridView;
    import android.widget.ImageView;
    
    public class Touch extends Activity implements OnTouchListener {
    private static final String TAG = "Touch";
    
    private static final float MIN_ZOOM = 1.0f;
    private static final float MAX_ZOOM = 5.0f;
    
    // These matrices will be used to move and zoom image
    Matrix matrix = new Matrix();
    Matrix savedMatrix = 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 start = new PointF();
    PointF mid = new PointF();
    float oldDist = 1f;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
       ImageView view = (ImageView) findViewById(R.id.imageView);
       //view.setLayoutParams(new GridView.LayoutParams(85, 85));
       view.setScaleType(ImageView.ScaleType.FIT_CENTER);
       view.setOnTouchListener(this);   
    }
    
    public boolean onTouch(View v, MotionEvent event) {
       ImageView view = (ImageView) v;
       view.setScaleType(ImageView.ScaleType.MATRIX);
       float scale;
    
       // Dump touch event to log
       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" );
          mode = DRAG;
          break;
       case MotionEvent.ACTION_UP: //first finger lifted
       case MotionEvent.ACTION_POINTER_UP: //second finger lifted
          mode = NONE;
          Log.d(TAG, "mode=NONE" );
          break;
       case MotionEvent.ACTION_POINTER_DOWN: //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) { //movement of first finger
             matrix.set(savedMatrix);
             if (view.getLeft() >= -392){
                matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
             }
          }
          else if (mode == ZOOM) { //pinch zooming
             float newDist = spacing(event);
             Log.d(TAG, "newDist=" + newDist);
             if (newDist > 5f) {
                matrix.set(savedMatrix);
                scale = newDist / oldDist; **//thinking i need to play around with this value to limit it**
                matrix.postScale(scale, scale, mid.x, mid.y);
             }
          }
          break;
       }
    
       // Perform the transformation
       view.setImageMatrix(matrix);
    
       return true; // indicate event was handled
    }
    
    private float spacing(MotionEvent event) {
       float x = event.getX(0) - event.getX(1);
       float y = event.getY(0) - event.getY(1);
       return FloatMath.sqrt(x * x + y * y);
    }
    
    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(TAG, sb.toString());
    }
    }
    
    package org.example.touch;
    导入android.app.Activity;
    导入android.graphics.Bitmap;
    导入android.graphics.Matrix;
    导入android.graphics.PointF;
    导入android.os.Bundle;
    导入android.util.FloatMath;
    导入android.util.Log;
    导入android.view.MotionEvent;
    导入android.view.view;
    导入android.view.view.OnTouchListener;
    导入android.widget.GridView;
    导入android.widget.ImageView;
    公共类Touch扩展了活动实现OnTouchListener{
    私有静态最终字符串TAG=“Touch”;
    专用静态最终浮点最小值\缩放=1.0f;
    专用静态最终浮动最大缩放=5.0f;
    //这些矩阵将用于移动和缩放图像
    矩阵=新矩阵();
    矩阵savedMatrix=新矩阵();
    //我们可能处于这三种状态之一
    静态最终int NONE=0;
    静态最终整数阻力=1;
    静态最终整数缩放=2;
    int模式=无;
    //记住一些关于缩放的事情
    PointF start=新的PointF();
    PointF mid=新的PointF();
    浮动oldDist=1f;
    @凌驾
    创建时的公共void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ImageView=(ImageView)findViewById(R.id.ImageView);
    //view.setLayoutParams(新的GridView.LayoutParams(85,85));
    view.setScaleType(ImageView.ScaleType.FIT_CENTER);
    view.setOnTouchListener(这个);
    }
    公共布尔onTouch(视图v,运动事件){
    ImageView视图=(ImageView)v;
    view.setScaleType(ImageView.ScaleType.MATRIX);
    浮标;
    //将触摸事件转储到日志
    dumpEvent(事件);
    //在这里处理触摸事件。。。
    开关(event.getAction()&MotionEvent.ACTION\u掩码){
    case MotionEvent.ACTION_DOWN://仅首指向下
    savedMatrix.set(矩阵);
    set(event.getX(),event.getY());
    Log.d(标记“mode=DRAG”);
    模式=拖动;
    打破
    case MotionEvent.ACTION_UP://举起第一个手指
    case MotionEvent.ACTION\u POINTER\u UP://举起食指
    模式=无;
    Log.d(标记“mode=NONE”);
    打破
    case MotionEvent.ACTION\u POINTER\u DOWN://食指向下
    oldDist=间距(事件);
    Log.d(标记“oldDist=“+oldDist”);
    如果(旧区>5f){
    savedMatrix.set(矩阵);
    中点(中点,事件);
    模式=缩放;
    Log.d(标记“mode=ZOOM”);
    }
    打破
    case MotionEvent.ACTION\u移动:
    如果(模式==拖动){//第一个手指的移动
    矩阵集(savedMatrix);
    if(view.getLeft()>=-392){
    postTranslate(event.getX()-start.x,event.getY()-start.y);
    }
    }
    如果(mode==ZOOM){//pinch缩放,则为else
    float newDist=间距(事件);
    Log.d(标记“newDist=“+newDist”);
    如果(新距离>5f){
    矩阵集(savedMatrix);
    scale=newDist/oldDist;**//我想我需要使用这个值来限制它**
    矩阵。后标度(标度、标度、中x、中y);
    }
    }
    打破
    }
    //执行转换
    视图.setImageMatrix(矩阵);
    返回true;//指示事件已处理
    }
    专用浮动间距(MotionEvent事件){
    float x=event.getX(0)-event.getX(1);
    float y=event.getY(0)-event.getY(1);
    返回FloatMath.sqrt(x*x+y*y);
    }
    专用空心中点(点F点、MotionEvent事件){
    float x=event.getX(0)+event.getX(1);
    float y=event.getY(0)+event.getY(1);
    点集(x/2,y/2);
    }
    /**在LogCat视图中显示事件以进行调试*/
    私有void转储事件(MotionEvent事件){
    字符串名称[]={“向下”、“向上”、“移动”、“取消”、“外部”,
    “指针向下”、“指针向上”、“7?”、“8?”、“9?”;
    StringBuilder sb=新的StringBuilder();
    int action=event.getAction();
    int actionCode=action&MotionEvent.action\u掩码;
    附加(名称[动作代码]);
    如果(actionCode==MotionEvent.ACTION\u指针\u向下
    ||actionCode==MotionEvent.ACTION(指针向上){
    某人追加(“(pid”)。追加(
    动作>>MotionEvent.action\u指针\u ID\u移位);
    某人加上(“)”;
    }
    某人加上(“[”);
    for(int i=0;i
    main.xml(相当简单,没有什么真正复杂的):

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent" >
    <ImageView android:id="@+id/imageView"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:src="@drawable/map"
         android:scaleType="matrix" >
    </ImageView>
    </FrameLayout>
    
    
    
    AndroidManifest.xml(仅添加了主题,因此没有标题栏且全屏显示)


    使用
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="org.example.touch"
      android:versionCode="7"
      android:versionName="1.0" >
    <application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
      <activity android:name=".Touch"
            android:label="@string/app_name" >
         <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
      </activity>
    </application>
    <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="7" />
    </manifest>
    
    private void limitZoom(Matrix m) {
    
        float[] values = new float[9];
        m.getValues(values);
        float scaleX = values[Matrix.MSCALE_X];
        float scaleY = values[Matrix.MSCALE_Y];
        if(scaleX > MAX_ZOOM) {
            scaleX = MAX_ZOOM;
        } else if(scaleX < MIN_ZOOM) {
            scaleX = MIN_ZOOM;
        }
    
        if(scaleY > MAX_ZOOM) {
            scaleY = MAX_ZOOM;
        } else if(scaleY < MIN_ZOOM) {
            scaleY = MIN_ZOOM;
        }
    
        values[Matrix.MSCALE_X] = scaleX;
        values[Matrix.MSCALE_Y] = scaleY; 
        m.setValues(values);
    }
    
    private void limitDrag(Matrix m) {
        float[] values = new float[9];
        m.getValues(values);
        float transX = values[Matrix.MTRANS_X];
        float transY = values[Matrix.MTRANS_Y];
        float scaleX = values[Matrix.MSCALE_X];
        float scaleY = values[Matrix.MSCALE_Y];
    
        ImageView iv = (ImageView)findViewById(R.id.photo_view);
        Rect bounds = iv.getDrawable().getBounds();
        int viewWidth = getResources().getDisplayMetrics().widthPixels;
        int viewHeight = getResources().getDisplayMetrics().heightPixels;
    
        int width = bounds.right - bounds.left;
        int height = bounds.bottom - bounds.top;
    
        float minX = (-width + 20) * scaleX; 
        float minY = (-height + 20) * scaleY;
    
        if(transX > (viewWidth - 20)) {
            transX = viewWidth - 20;
        } else if(transX < minX) {
            transX = minX;
        }
    
        if(transY > (viewHeight - 80)) {
            transY = viewHeight - 80;
        } else if(transY < minY) {
            transY = minY;
        }
    
        values[Matrix.MTRANS_X] = transX;
        values[Matrix.MTRANS_Y] = transY; 
        m.setValues(values);
    }
    
    WebView webView = new WebView(this);
    webView.setBackgroundColor(0xff000000);
    webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
    webView.getSettings().setBuiltInZoomControls(true);
    webView.getSettings().setSupportZoom(true);
    //webView.getSettings().setDisplayZoomControls(false);  // API 11
    webView.loadDataWithBaseURL(null, getHtml(), "text/html", "UTF-8", null);
    mainView.addView(webView, -1, -2);
    
    float maxX = minX+viewWidth; 
    int offsetY = 80;
            float maxY = minY+viewHeight-offsetY;
           if(x>maxX){
               mPosX = maxX;
           }
           if(x<minX){
               mPosX = minX;
           }
           if(y>maxY){
               mPosY = maxY;
           }
           if(y<minY){
               mPosY = minY;
           }
    
    public class Touch implements OnTouchListener {  
    
     // These matrices will be used to move and zoom image  
    public static Matrix matrix = new Matrix();  
    public static Matrix savedMatrix = 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;
    private static final float MAX_ZOOM = (float) 3;
    private static final float MIN_ZOOM = 1;  
     int mode = NONE;  
    
     // Remember some things for zooming  
     PointF start = new PointF();  
     PointF mid = new PointF();  
     float oldDist = 1f;  
    
     int width,height;
    
     @Override  
     public boolean onTouch(View v, MotionEvent event) {
    
    
      ImageView view = (ImageView) v;
      Rect bounds = view.getDrawable().getBounds();
    
      width = bounds.right - bounds.left;
      height = bounds.bottom - bounds.top;
      // Dump touch event to log  
      dumpEvent(event);  
    
      // Handle touch events here...  
      switch (event.getAction() & MotionEvent.ACTION_MASK) {  
      case MotionEvent.ACTION_DOWN:  
       savedMatrix.set(matrix);  
       start.set(event.getX(), event.getY());  
       mode = DRAG;  
       break;  
      case MotionEvent.ACTION_POINTER_DOWN:  
       oldDist = spacing(event);  
       if (oldDist > 10f) {  
        savedMatrix.set(matrix);  
        midPoint(mid, event);  
        mode = ZOOM;  
       }  
       break;  
      case MotionEvent.ACTION_UP:  
      case MotionEvent.ACTION_POINTER_UP:  
       mode = NONE;  
       break;  
      case MotionEvent.ACTION_MOVE:  
       if (mode == DRAG) {  
        // ...      
        matrix.set(savedMatrix);  
        matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);      
       } else if (mode == ZOOM) {  
        float newDist = spacing(event);  
        if (newDist > 10f) {  
         matrix.set(savedMatrix);  
         float scale = newDist / oldDist;  
         matrix.postScale(scale, scale, mid.x, mid.y);  
        }  
       }  
       break;  
      }  
    //----------------------------------------------------
      limitZoom(matrix);
      limitDrag( matrix);
    //----------------------------------------------------  
      view.setImageMatrix(matrix);  
      return true; // indicate event was handled  
     }  
    
     /** 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("]");  
     }  
    
     /** Determine the space between the first two fingers */  
     private float spacing(MotionEvent event) {  
      float x = event.getX(0) - event.getX(1);  
      float y = event.getY(0) - event.getY(1);  
      return FloatMath.sqrt(x * x + y * y);  
     }  
    
     /** Calculate the mid point of the first 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);  
     }  
    
     private void limitZoom(Matrix m) {
    
            float[] values = new float[9];
            m.getValues(values);
            float scaleX = values[Matrix.MSCALE_X];
            float scaleY = values[Matrix.MSCALE_Y];
            if(scaleX > MAX_ZOOM) {
                scaleX = MAX_ZOOM;
            } else if(scaleX < MIN_ZOOM) {
                scaleX = MIN_ZOOM;
            }
    
            if(scaleY > MAX_ZOOM) {
                scaleY = MAX_ZOOM;
            } else if(scaleY < MIN_ZOOM) {
                scaleY = MIN_ZOOM;
            }
    
            values[Matrix.MSCALE_X] = scaleX;
            values[Matrix.MSCALE_Y] = scaleY; 
            m.setValues(values);
        }
    
    
     private void limitDrag(Matrix m) {
    
            float[] values = new float[9];
            m.getValues(values);
            float transX = values[Matrix.MTRANS_X];
            float transY = values[Matrix.MTRANS_Y];
            float scaleX = values[Matrix.MSCALE_X];
            float scaleY = values[Matrix.MSCALE_Y];
    //--- limit moving to left ---
            float minX = (-width + 0) * (scaleX-1); 
            float minY = (-height + 0) * (scaleY-1);
    //--- limit moving to right ---     
            float maxX=minX+width*(scaleX-1);
            float maxY=minY+height*(scaleY-1);
            if(transX>maxX){transX = maxX;}
            if(transX<minX){transX = minX;}
            if(transY>maxY){transY = maxY;}
            if(transY<minY){transY = minY;}
            values[Matrix.MTRANS_X] = transX;
            values[Matrix.MTRANS_Y] = transY; 
            m.setValues(values);
        }
    
    }