【问题标题】:OnTouch giving different position, compared to ImageView position与 ImageView 位置相比,OnTouch 给出不同的位置
【发布时间】:2020-03-27 04:00:59
【问题描述】:

我有许多以编程方式定义的ImageViews,它们在数组中都有自己的位置,如下所示:

const1Positions = arrayOf(
  Point(dpToPx(349), dpToPx(258)),
  Point(dpToPx(491), dpToPx(302)), 
  Point(dpToPx(495), dpToPx(429)),
  Point(dpToPx(669), dpToPx(524)), 
  Point(dpToPx(600), dpToPx(618))
)

这里是dpToPx

fun Activity.dpToPx(dp: Int): Int {
  return TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP,
    dp.toFloat(), 
    resources.displayMetrics
  ).roundToInt()
}

我正在尝试将setOnTouchListener 分配给每个ImageView(当我在for 中初始化它们时,我也会调用imageview.setOnTouchListener...

但我的触摸无法识别。 我也尝试过,而不是在每个ImageView 中添加onTouchListener,而是在主视图中添加onTouchEvent,如果event.x == imageview.x(用户触摸了ImageView),请执行操作。但是event.ximage.x 是不同的。

这是我的setOnTouchListener

view.setOnTouchListener { v, event ->
    when (event.actionMasked) {
      MotionEvent.ACTION_DOWN -> {
        Log.d("DEBUG_TAG", event.x.toString())
        true
      }
      MotionEvent.ACTION_UP -> {
        Log.d("DEBUG_TAG", "Action was UP")
        Log.d("test", const1Positions[0].x.toString())
        Log.d("test2", view.width.toString())
        true
      }
      MotionEvent.ACTION_MOVE -> {
        Log.d("DEBUG_TAG", "Action was MOVE")
        true
      }
      MotionEvent.ACTION_CANCEL -> {
        Log.d("DEBUG_TAG", "Action was CANCEL")
        true
      }
      MotionEvent.ACTION_OUTSIDE -> {
        Log.d(
          "DEBUG_TAG",
          "Movement occurred outside bounds of current screen element"
        )
        true
      }
      else -> super.onTouchEvent(event)
    }
}

我的布局宽度和高度都比屏幕大 2 倍,我可以放大/缩小和滚动,但我没有使用ScrollView。我正在使用 GitHub 上提供的自定义布局。

params.width = view.resources.displayMetrics.widthPixels * 2
params.height = view.resources.displayMetrics.heightPixels * 2
view.layoutParams = params

我使用Log 来比较触摸位置、ImageView 位置和布局大小。但结果完全不同:

2020-03-25 19:31:07.796 26112-26112/com.example.android.bonte_android D/DEBUG_TAG: 395.63367 2020-03-25 19:31:07.833 26112-26112/com.example.android.bonte_android D/测试:890 2020-03-25 19:31:07.834 26112-26112/com.example.android.bonte_android D/test2: 2160

屏幕位置是以2160为基准的,所以显示的是890。但是即使我触摸屏幕,event.x的位置显示的是395而不是890,event.x接收到的最大位置是1080(实际手机宽度),而不是 2160(布局最大宽度)。有谁知道为什么会这样?

与其将onTouchListener 添加到View,不如添加到所有ImageViews,但是当我这样做时,正如我所说,onTouchListener 无法识别任何触摸,

【问题讨论】:

标签: java android kotlin android-activity android-touch-event


【解决方案1】:

希望this 的回答(由 Piyush 提供)会让你满意:

MotionEvent 有时会返回相对于视图的绝对 X 和 Y 坐标,有时会返回与前一个运动事件的相对坐标。

getRawX() 和 getRawY() 保证返回相对于设备屏幕的绝对坐标。

而 getX() 和 getY() 应该返回你的坐标,相对于视图,派发它们。

UPD:在 XML 属性 app:hasClickableChildren="true" 中添加 ZoomLayout 可修复问题。

【讨论】:

  • 这两种方法都返回相同的值,基于我的手机屏幕。我发现由于我将外部库用作布局,因此无法识别对图像视图的触摸。当我删除它并尝试使用 ScrollView/Horizo​​ntalScrollView 时,我收到了触摸事件。
  • @LucasRodrigues 我可以请你给我这个库的链接吗?
  • 这里是:github.com/natario1/ZoomLayout 当我将 onTouchEvent 添加到我的 FrameLayout(我的图像视图所在的位置)时,我会收到这些事件。 FrameLayout 位于 ZoomLayout 内部。但是当我将 onTouchListener 直接添加到图像视图时,它无法识别触摸。我选择这个 ZoomLayout 是因为 ScrollView/Horizo​​ntalScrollView 没有 DiagonalScroll,而且我还得实现缩放。
  • 您是否在 XML 属性 app:hasClickableChildren="true" 中添加了 ZoomLayout
猜你喜欢
  • 2015-03-23
  • 2015-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 2019-12-24
  • 2019-05-09
相关资源
最近更新 更多