Android,在ImageView上缺少触摸事件

时间:2012-12-24 16:13:48

标签: android touch android-imageview

我已经明白这是我的代码问题。但我无法找出问题所在。我下载了一个“示例项目”来使用touchListener,它可以工作,但如果我尝试在我的项目中做同样的事情,突然我只能得到“按下按钮”事件。

的活动:

  @Override
  protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.navigator_layout);

    b = this.getIntent().getStringArrayExtra("building");

    cv = (MapView) this.findViewById(R.id.map); 

            MapMovement mm = new MapMovement(cv);

            compass = new Compass(this, cv, debug);
}

map.xml:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/black"
    android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >

    <it.inav.graphics.MapView
        android:id="@+id/map"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_centerInParent="true" />

  </RelativeLayout>

我省略了MapView的某些部分,在那里我得到了图像,依此类推,询问你认为是否重要:

  public class MapView extends ImageView  {

...

        public MapView(Context context, AttributeSet attrs, int defStyle) {
              super(context, attrs, defStyle);
        }

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

        public MapView(Context context) {
              super(context);
        }

        public void init(List<Floor> floors) {
              this.floors = floors;
              setFocusable(true);
        }


        private void setInitialZoom() {

              if (screen_center == null)
                    return;

              // recupero la dimensione dell'immagine
              int image_width = bmp.getWidth();
              int image_heigth = bmp.getHeight();


              int longest_i = image_width;
              if (longest_i < image_heigth)
                    longest_i = image_heigth;

              float longest_s = screen_center.x * 2;

              if (longest_s < screen_center.y * 2)
                    longest_s = screen_center.y * 2;

              float zoom = (float)longest_s / longest_i;

              this.min_zoom = zoom;
              this.zoom = zoom;

              setImageCenter(null);
        }


        private void setZoom(float zoom) {

              if (zoom < min_zoom)
                    this.zoom = min_zoom;

              else if (zoom > 1)
                    this.zoom = 1;

              else 
                    this.zoom = zoom;

              this.invalidate();
        }

        private void setImageCenter(PointF posizione) {

              if (posizione != null) 
                    image_center = new PointF(posizione.x, posizione.y);
              else 
                    image_center = new PointF(bmp.getWidth(), bmp.getHeight());
        }


        private void prepareImage(Canvas canvas) {

              canvas.rotate((float)(bearing - selected_floor.bearing), screen_center.x, screen_center.y);


              // scalo l'immagine 
              image = new Matrix();
              image.setScale(zoom, zoom);

              Paint drawPaint = new Paint();
              drawPaint.setAntiAlias(true);
              drawPaint.setFilterBitmap(true);

              float centerScaledWidth = image_center.x * zoom / 2;
              float centerScaledHeigth = image_center.y * zoom / 2;

              image.postTranslate(screen_center.x -  centerScaledWidth, 
            screen_center.y - centerScaledHeigth);

              canvas.drawBitmap(bmp, image, drawPaint);

              canvas.save();
              canvas.restore();
        }

        private void drawMarkers(Canvas canvas) {
              Paint drawPaint = new Paint();
              drawPaint.setAntiAlias(true);

              drawPaint.setColor(Color.WHITE);
              canvas.drawCircle(screen_center.x, screen_center.y, MARKER_DIAMETER + 1, drawPaint);

              drawPaint.setColor(Color.RED);
              canvas.drawCircle(screen_center.x, screen_center.y, MARKER_DIAMETER, drawPaint);

              canvas.save();
              canvas.restore();
        }

        private void setScreenCenter() {

              if (screen_center != null)
                    return; 

              // recupero la dimensione dello schermo
              int screen_height = getMeasuredHeight();
              int screen_width = getMeasuredWidth();

              if ((screen_height == 0) || (screen_width == 0))
                    return;

              screen_center = new PointF(screen_width / 2, screen_height / 2);
              setInitialZoom();
        }

        @Override
        public void draw(Canvas canvas) {

              setScreenCenter();

              if (selected_floor != null) {

                    prepareImage(canvas);
                    drawMarkers(canvas);
              }
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
              int measuredWidth = measure(widthMeasureSpec);
              int measuredHeight = measure(heightMeasureSpec);
              setMeasuredDimension(measuredWidth, measuredHeight);
        }

        private int measure(int measureSpec) {
              int result = 0;

              // Decode the measurement specifications.
              int specMode = MeasureSpec.getMode(measureSpec);
              int specSize = MeasureSpec.getSize(measureSpec);
              if (specMode == MeasureSpec.UNSPECIFIED) {
                    // Return a default size of 200 if no bounds are specified.
                    result = 200;
              } else {
                    // As you want to fill the available space
                    // always return the full available bounds.
                    result = specSize;
              }
              return result;
        }

        public void setBearing(float _bearing) {
              bearing = _bearing;
        }
  }

触摸听众,我把它放在另一个班级。 MapMovement:

  public class MapMovement implements OnTouchListener {

        ...

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

        public MapMovement(MapView mapView) {

              this.mapView = mapView;
              mapView.setOnTouchListener(this);
        }

        public void setImageCenter(PointF p) {
              this.image_center = p;
        }

        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("event", sb.toString());
        }

        @Override
        public boolean onTouch(View v, MotionEvent event) {

              // Dump touch event to log
          dumpEvent(event);

              return false;
        }
  }

当我尝试在MapView上执行“DRAG”时,这是输出日志:

  12-24 09:41:58.412: D/event(31342): event ACTION_DOWN[#0(pid 0)=85,248]
  12-24 09:42:01.752: D/event(31342): event ACTION_DOWN[#0(pid 0)=106,126]
  12-24 09:42:02.466: D/event(31342): event ACTION_DOWN[#0(pid 0)=96,286]

日志代码与我下载的测试项目相同,这是我可以得到的所有输出。没有ACTION_UP,没有ACTION_MOVEMENT,没有。

我不知道问题出在哪里或在哪里。我想要的只是使用触摸事件在活动中移动图像,但似乎我只能获得一个触摸事件,ACTION_DOWN。

我发布了代码的所有部分,我认为这可能是错误。如果我认为问题肯定出现在一个类或布局中,我会发布它而不是这一堆代码,我已经为你编辑了15分钟。

非常感谢你的帮助。如果你不知道哪个错误不是问题。但你不能来这里告诉我“更具体”,因为如果我能“更具体”,我就不会在这里问你,因为我会自己解决问题。

1 个答案:

答案 0 :(得分:-1)

解决方案很简单,在 MapMovement 中, onTouch 必须返回 true 而不是 false

非常感谢你的帮助。 (我自然很讽刺)