安卓ImageView的:设置阻力和双指缩放参数缩放、阻力、参数、ImageView

2023-09-11 20:30:26 作者:氧气男神

我目前正在开发针对Android(我的第一个应用程序)的应用程序,它可以让用户看到地铁路线图,并能捏缩放,拖动左右。

我目前正在修改的Andr​​oid你好,第3版中的code,得到了捏缩放和拖动工作。我使用的是矩阵作为我的布局规模。

不过,我现在有三个问题:

我试了很多东西来限制阻力参数,但我似乎无法阻止它被拖走父视图(和实际上可以从视野中消失)。我试着在XML文件中设置布局参数,它是行不通的。

我可以捏缩放不错,但我有麻烦,再次,限制变焦量。我试图玩弄设置max_zoom和min_zoom限制比例值(我会发布后,我的code)

我也有麻烦试图映射一个坐标上我的形象,使人们可以点击某些部分(该整点是让用户单击站地图,查看相关信息)

我有一种感觉,我遇到麻烦了,因为我使用的是矩阵的规模。

下面是我目前的code:

Touch.java

 包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;

公共类触摸扩展活动实现OnTouchListener {
私有静态最后字符串变量=触摸;

私有静态最终浮动MIN_ZOOM = 1.0F;
私有静态最终浮动MAX_ZOOM = 5.0F;

//这些矩阵将用于移动和放大图像
字模=新的Matrix();
矩阵savedMatrix =新的Matrix();

//我们可以在这3个状态之一
静态最终诠释无= 0;
静态最终诠释DRAG = 1;
静态最终诠释ZOOM = 2;
INT模式=无;

//记住一些东西放大
的PointF开始=新的PointF();
的PointF中期=新的PointF();
浮oldDist = 1F;

@覆盖
公共无效的onCreate(包savedInstanceState){
   super.onCreate(savedInstanceState);
   的setContentView(R.layout.main);
   ImageView的观点=(ImageView的)findViewById(R.id.imageView);
   //view.setLayoutParams(new GridView.LayoutParams(85,85));
   view.setScaleType(ImageView.ScaleType.FIT_CENTER);
   view.setOnTouchListener(本);
}

公共布尔onTouch(视图V,MotionEvent事件){
   ImageView的观点=(ImageView的)V;
   view.setScaleType(ImageView.ScaleType.MATRIX);
   浮规模;

   //转储触摸事件日志
   dumpEvent(事件);

   //这里处理触摸事件...
   开关(event.getAction()及MotionEvent.ACTION_MASK){

   案例MotionEvent.ACTION_DOWN://第一指仅下跌
      savedMatrix.set(矩阵);
      start.set(event.getX(),event.getY());
      Log.d(TAG模式= DRAG);
      模式=阻力;
      打破;
   案例MotionEvent.ACTION_UP://第一手指抬起
   案例MotionEvent.ACTION_POINTER_UP://第二根手指抬起
      模式=无;
      Log.d(TAG模式= NONE);
      打破;
   案例MotionEvent.ACTION_POINTER_DOWN://第二根手指向下
      oldDist =间距(事件);
      Log.d(TAG,oldDist =+ oldDist);
      如果(oldDist> 5F){
         savedMatrix.set(矩阵);
         中点(中,事件);
         模式=变焦;
         Log.d(TAG模式= ZOOM);
      }
      打破;

   案例MotionEvent.ACTION_MOVE:
      如果(模式==拖动){//第一手指的运动
         matrix.set(savedMatrix);
         如果(view.getLeft()> = -392){
            matrix.postTranslate(event.getX() -  start.x,event.getY() -  start.y);
         }
      }
      否则,如果(模式==变焦){//捏缩放
         浮newDist =间距(事件);
         Log.d(TAG,newDist =+ newDist);
         如果(newDist> 5F){
            matrix.set(savedMatrix);
            规模= newDist / oldDist; ** //想我需要玩弄此值来限制它**
            matrix.postScale(规模化,规模化,mid.x,mid.y);
         }
      }
      打破;
   }

   //执行转换
   view.setImageMatrix(矩阵);

   返回true; //表示事件已经被处理
}

私人浮动间距(MotionEvent事件){
   浮X = event.getX(0) -  event.getX(1);
   浮Y = event.getY(0) -  event.getY(1);
   返回FloatMath.sqrt(X * X + Y * Y);
}

私人无效中点(的PointF点,MotionEvent事件){
   浮X = event.getX(0)+ event.getX(1);
   浮Y = event.getY(0)+ event.getY(1);
   point.set(X / 2,Y / 2);
}

/ **显​​示在LogCat中查看事件,调试* /
私人无效dumpEvent(MotionEvent事件){
   字符串名称[] = {DOWN,UP,移动,取消,外,
      POINTER_DOWN,POINTER_UP,7? 8? 9? };
   StringBuilder的SB =新的StringBuilder();
   INT行动= event.getAction();
   INT行动code =动作和放大器; MotionEvent.ACTION_MASK;
   sb.append(事件ACTION_).append(名称[动作code]);
   如果(动作code == MotionEvent.ACTION_POINTER_DOWN
         ||行动code == MotionEvent.ACTION_POINTER_UP){
      sb.append((PID).append(
      作用>> MotionEvent.ACTION_POINTER_ID_SHIFT);
      sb.append());
   }
   sb.append([);
   的for(int i = 0; I< event.getPointerCount();我++){
      sb.append(#).append(ⅰ);
      sb.append((PID).append(event.getPointerId(ⅰ));
      sb.append()=).append((int)的event.getX(ⅰ));
      sb.append(,).append((int)的event.getY(ⅰ));
      如果第(i + 1&其中; event.getPointerCount())
         sb.append(;);
   }
   sb.append(]);
   Log.d(TAG,sb.toString());
}
}
 

main.xml中(而不是简单的没有什么复杂的):

 < XML版本=1.0编码=UTF-8&GT?;
<的FrameLayout
  的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
  机器人:layout_width =FILL_PARENT
  机器人:layout_height =FILL_PARENT>
< ImageView的机器人:ID =@ + ID / ImageView的
     机器人:layout_width =FILL_PARENT
     机器人:layout_height =FILL_PARENT
     机器人:SRC =@可绘制/图
     机器人:scaleType =矩阵>
< / ImageView的>
< /的FrameLayout>
 
单手操作毫无压力 安卓单指缩放技巧

AndroidManifest.xml中(只加了这个主题,所以没有标题栏,是全屏)

 <舱单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
  包=org.example.touch
  安卓版code =7
  机器人:VERSIONNAME =1.0>
<应用机器人:图标=@可绘制/图标机器人:标签=@字符串/ APP_NAME安卓主题=@安卓风格/ Theme.NoTitleBar.Fullscreen>
  <活动机器人:名称=触摸
        机器人:标签=@字符串/ APP_NAME>
     <意向滤光器>
        <作用机器人:名称=android.intent.action.MAIN/>
        <类机器人:名称=android.intent.category.LAUNCHER/>
     &所述; /意图滤光器>
  < /活性GT;
< /用途>
<使用-SDK安卓的minSdkVersion =3安卓targetSdkVersion =7/>
< /舱单>
 

解决方案

我刚刚创建的:

https://github.com/jasonpolites/gesture-imageview

可能是有用的人......

I am currently developing for Android (my first app) an application which lets users see the subway map and be able to pinch zoom and drag around.

I am currently modifying the code found in Hello Android, 3rd Edition and got the pinch zooming and dragging to work. I'm using Matrix as my layout scale.

However I now have 3 problems:

I tried many things to limit the drag parameters but I can't seem to stop it being dragged off the parent view (and can actually disappear from view). I've tried setting layout parameters in the XML file and it just doesn't work.

I can pinch zoom fine but I have trouble, again, limiting the amount of zoom. I'm trying to play around with setting a max_zoom and min_zoom to limit the scaling value (i will post my code after)

I also have trouble trying to map a coordinate on my image so that people can click on certain parts (the whole point of this is to let users click a station on the map and view information about it)

I have a feeling i'm having trouble because I'm using the matrix scale.

Here is my current code:

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());
}
}

main.xml (rather simple nothing really complicated):

<?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 (only added the theme so there is no title bar and is full screen)

<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>

解决方案

I just created this:

https://github.com/jasonpolites/gesture-imageview

Might be useful for someone...