1

I have many ImageViews defined programmatically, and they have their positions in arrays, like that:

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

Here is dpToPx:

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

I'm trying to setOnTouchListener to every ImageView (when I initialize them inside a for, I also call imageview.setOnTouchListener...)

But my touch isn't recognized. I also tried, instead of adding an onTouchListener to every ImageView, add the onTouchEvent in the main view and, if the event.x == imageview.x (the user touched the ImageView), do the actions. But the event.x and image.x are different.

Here's my 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)
    }
}

My layout width and height are both 2 times bigger than the screen, and I can zoom in/out and scroll, but I'm not using ScrollView. I'm using a custom Layout available on GitHub.

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

I'm using Log to compare the touch position, the ImageView position and the layout size. But the results are completely different:

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/test: 890
2020-03-25 19:31:07.834 26112-26112/com.example.android.bonte_android D/test2: 2160

The screen position is based on 2160, so It shows 890. But even when I touch on the screen, the event.x position shows 395 instead of 890, and the maximum position that event.x receives is 1080 (the real phone width), and not 2160 (the layout maximum width). Does anyone know why this happens?

Instead of adding onTouchListener to View, It'd be better to add to all of the ImageViews, but when I do that, as I said, onTouchListener doesn't recognize any touch,

ardiien
  • 767
  • 6
  • 26
Lucas
  • 87
  • 1
  • 8
  • 2
    Does this answer your question? [Difference between MotionEvent.getRawX and MotionEvent.getX](https://stackoverflow.com/questions/20636163/difference-between-motionevent-getrawx-and-motionevent-getx) – ardiien Mar 26 '20 at 00:18
  • Please, read https://stackoverflow.com/help/how-to-ask. It will help you to create a well-formatted question before posting. – ardiien Mar 26 '20 at 00:25
  • @YaroslavOvdiienko Thank u for the tips and sorry for my bad formatting, I'll check it! – Lucas Mar 26 '20 at 01:07

1 Answers1

0

I hope this answer (by Piyush) will satisfy you:

MotionEvent will sometimes return absolute X and Y coordinates relative to the view, and sometimes relative coordinates to the previous motion event.

getRawX() and getRawY() that is guaranteed to return absolute coordinates, relative to the device screen.

While getX() and getY(), should return you coordinates, relative to the View, that dispatched them.

UPD: adding to ZoomLayout in XML property app:hasClickableChildren="true" fix the issue.

ardiien
  • 767
  • 6
  • 26
  • Both methods are returning the same value, based on my phone screen. I found out that the touches on imageviews don't get recognized because of the external library that I'm using as Layout. When I removed it and tried with ScrollView/HorizontalScrollView, I received the touch events. – Lucas Mar 26 '20 at 01:05
  • @LucasRodrigues may I ask you to give me a link to this lib? – ardiien Mar 26 '20 at 01:12
  • peruse https://developer.android.com/training/gestures/viewgroup. – ardiien Mar 26 '20 at 01:23
  • Here it is: https://github.com/natario1/ZoomLayout I receive the events when I add the onTouchEvent to my FrameLayout (where my imageviews are). The FrameLayout is inside the ZoomLayout. But when I add the onTouchListener directly to the imageviews, it doesn't recognize the touches. I chose this ZoomLayout because ScrollView/HorizontalScrollView don't have DiagonalScroll, and I'd also have to implement zoom. – Lucas Mar 26 '20 at 03:31
  • did you add to `ZoomLayout` in XML property `app:hasClickableChildren="true"`? – ardiien Mar 26 '20 at 16:45
  • Anyway, why for you not enough use `onTouchEvent` from your `FrameLayout`? – ardiien Mar 26 '20 at 16:50
  • Oh, the problem was that I didn't add this property! I should had paid more attention on it. In fact, I added this property before adding the onTouchListener, but I have a customview that create paths between each imageview, so the imageview gets connected, but this property, when enable, changes the paths sizes and position, they start to appear in the top-left part part of screen, and smaller, instead of being drawn between the imageviews. But that's another problem and I'll check how this property works to try to fix it. Thanks! – Lucas Mar 26 '20 at 17:36
  • It's not enough because each imageview will represent an action that the user will be able to do. So, when the user touch one imageview, it will use her id to get the action and show on the screen. It will also scroll the FrameLayout in a way the imageview will be in the center of it, and I'll also do a zoom animation in the imageview. – Lucas Mar 26 '20 at 17:37
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/210398/discussion-between-lucas-rodrigues-and-yaroslav-ovdiienko). – Lucas Mar 26 '20 at 18:01