MotionEvent.getX()/getY()返回偏移值,ImageView标记绘制位置异常
解决ImageView触摸坐标与绘制偏移的问题
核心问题是触摸坐标是ImageView控件的相对坐标,而你直接用这个坐标去绘制在原始尺寸的Bitmap上,当ImageView对图片进行了缩放/适配(比如默认的fitCenter缩放)时,两者的坐标体系不匹配,自然会出现偏移。
解决步骤
- 计算Bitmap在ImageView中的缩放比例和偏移量,把View的触摸坐标转换为Bitmap的实际像素坐标
- 绘制完成后刷新ImageView,让新绘制的标记显示出来
修改后的代码
ImageView mapImage = findViewById(R.id.mapImageView); Bitmap imageBitmap = BitmapFactory.decodeFile(projectfile2.getPath()).copy(Bitmap.Config.ARGB_8888, true); mapImage.setImageBitmap(imageBitmap); Bitmap pinBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.red_marker); mapImage.setOnTouchListener((view, motionEvent) -> { if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { ImageView iv = (ImageView) view; Drawable drawable = iv.getDrawable(); if (drawable == null) return true; // 获取Bitmap的原始尺寸 int bitmapWidth = drawable.getIntrinsicWidth(); int bitmapHeight = drawable.getIntrinsicHeight(); if (bitmapWidth == 0 || bitmapHeight == 0) return true; // 获取ImageView的显示尺寸 int viewWidth = iv.getWidth(); int viewHeight = iv.getHeight(); // 计算缩放比例(对应默认fitCenter的缩放逻辑) float scaleX = (float) viewWidth / bitmapWidth; float scaleY = (float) viewHeight / bitmapHeight; float scale = Math.min(scaleX, scaleY); // 计算Bitmap在ImageView中的居中偏移量 float offsetX = (viewWidth - bitmapWidth * scale) / 2; float offsetY = (viewHeight - bitmapHeight * scale) / 2; // 将触摸坐标转换为Bitmap的像素坐标 float touchX = (motionEvent.getX() - offsetX) / scale; float touchY = (motionEvent.getY() - offsetY) / scale; // 绘制标记(减去自身宽高一半,让标记中心对准触摸点) Canvas canvas = new Canvas(imageBitmap); canvas.drawBitmap(pinBitmap, touchX - pinBitmap.getWidth()/2, touchY - pinBitmap.getHeight()/2, null); // 刷新ImageView显示 iv.setImageBitmap(imageBitmap); Log.d("app123_X_and_Y", "转换后Bitmap坐标:" + touchX + " | " + touchY); } return true; });
XML补充说明
如果你的图片需要特定的显示适配方式,建议给ImageView明确设置scaleType,比如:
<ImageView android:id="@+id/mapImageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/rectangle" android:scaleType="fitCenter" <!-- 可根据需求替换为fitXY/centerCrop等 --> tools:srcCompat="@tools:sample/avatars" android:contentDescription="Map" />
额外提示
- 如果你的ImageView支持滚动/缩放,还要把滚动偏移量加入坐标计算
- 频繁修改原始Bitmap并刷新可能有性能损耗,建议用自定义View单独绘制标记层,避免修改原图
内容的提问来源于stack exchange,提问作者Phantom37
相关产品推荐
相关产品推荐

