OnTouchListerner shall not interpret swipes do open DrawerLayout as Long Click









up vote
4
down vote

favorite












I'm detecting clicks in my recyclerview using the OnItemTouchListener class below. Unfortunately, this does not work well when using a DrawerLayout. If I swipe to open the DrawerLayout/NavigationView, my OnItemTouchListener gets this event too and executes the onLongClick action.



This does not happen if I use the ViewHolders' View.OnLongClick. What's the little secret, Views' OnLongClickListener checks before firing an LongClick-event to detect that the drag-action is not a long click, but a gesture to open the drawer?



class OnItemTouchListener(context: Context, recyclerView: RecyclerView, private var onTouchCallback: ItemTouchListener) : RecyclerView.OnItemTouchListener 

//region Variables

private val gestureDetector: GestureDetector

//endregion

init
gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener()
override fun onSingleTapUp(e: MotionEvent?): Boolean
return true


override fun onLongPress(e: MotionEvent?)
val child: View? = recyclerView.findChildViewUnder(e!!.x, e.y)

if (child != null)
onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), e)


super.onLongPress(e)

)


//region TouchHandler

override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean
val child = rv.findChildViewUnder(e.x, e.y)

if (child != null && gestureDetector.onTouchEvent(e))
onTouchCallback.onItemClick(child, rv.getChildLayoutPosition(child), e)


return false


override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean)



override fun onTouchEvent(rv: RecyclerView, e: MotionEvent)



//endregion

interface ItemTouchListener
fun onItemClick(view: View, pos: Int, e: MotionEvent)
fun onItemLongClick(view: View, pos: Int, e: MotionEvent)


companion object
fun isViewClicked(container: View, @IdRes viewId: Int, e: MotionEvent): Boolean
val view = container.findViewById<View>(viewId)

val rect = Rect()
view.getGlobalVisibleRect(rect)

return view.isVisible && rect.contains(e.rawX.toInt(), e.rawY.toInt())












share|improve this question























  • You can avoid calling super in long press to notify system about you've already consumed long press.
    – Jeel Vankhede
    Nov 10 at 14:46











  • @JeelVankhede This method has no return type. The problem is that I do not want gestureDetector to detect a LongPress if I'm swiping to open the drawer...
    – the_dani
    Nov 10 at 14:48














up vote
4
down vote

favorite












I'm detecting clicks in my recyclerview using the OnItemTouchListener class below. Unfortunately, this does not work well when using a DrawerLayout. If I swipe to open the DrawerLayout/NavigationView, my OnItemTouchListener gets this event too and executes the onLongClick action.



This does not happen if I use the ViewHolders' View.OnLongClick. What's the little secret, Views' OnLongClickListener checks before firing an LongClick-event to detect that the drag-action is not a long click, but a gesture to open the drawer?



class OnItemTouchListener(context: Context, recyclerView: RecyclerView, private var onTouchCallback: ItemTouchListener) : RecyclerView.OnItemTouchListener 

//region Variables

private val gestureDetector: GestureDetector

//endregion

init
gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener()
override fun onSingleTapUp(e: MotionEvent?): Boolean
return true


override fun onLongPress(e: MotionEvent?)
val child: View? = recyclerView.findChildViewUnder(e!!.x, e.y)

if (child != null)
onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), e)


super.onLongPress(e)

)


//region TouchHandler

override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean
val child = rv.findChildViewUnder(e.x, e.y)

if (child != null && gestureDetector.onTouchEvent(e))
onTouchCallback.onItemClick(child, rv.getChildLayoutPosition(child), e)


return false


override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean)



override fun onTouchEvent(rv: RecyclerView, e: MotionEvent)



//endregion

interface ItemTouchListener
fun onItemClick(view: View, pos: Int, e: MotionEvent)
fun onItemLongClick(view: View, pos: Int, e: MotionEvent)


companion object
fun isViewClicked(container: View, @IdRes viewId: Int, e: MotionEvent): Boolean
val view = container.findViewById<View>(viewId)

val rect = Rect()
view.getGlobalVisibleRect(rect)

return view.isVisible && rect.contains(e.rawX.toInt(), e.rawY.toInt())












share|improve this question























  • You can avoid calling super in long press to notify system about you've already consumed long press.
    – Jeel Vankhede
    Nov 10 at 14:46











  • @JeelVankhede This method has no return type. The problem is that I do not want gestureDetector to detect a LongPress if I'm swiping to open the drawer...
    – the_dani
    Nov 10 at 14:48












up vote
4
down vote

favorite









up vote
4
down vote

favorite











I'm detecting clicks in my recyclerview using the OnItemTouchListener class below. Unfortunately, this does not work well when using a DrawerLayout. If I swipe to open the DrawerLayout/NavigationView, my OnItemTouchListener gets this event too and executes the onLongClick action.



This does not happen if I use the ViewHolders' View.OnLongClick. What's the little secret, Views' OnLongClickListener checks before firing an LongClick-event to detect that the drag-action is not a long click, but a gesture to open the drawer?



class OnItemTouchListener(context: Context, recyclerView: RecyclerView, private var onTouchCallback: ItemTouchListener) : RecyclerView.OnItemTouchListener 

//region Variables

private val gestureDetector: GestureDetector

//endregion

init
gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener()
override fun onSingleTapUp(e: MotionEvent?): Boolean
return true


override fun onLongPress(e: MotionEvent?)
val child: View? = recyclerView.findChildViewUnder(e!!.x, e.y)

if (child != null)
onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), e)


super.onLongPress(e)

)


//region TouchHandler

override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean
val child = rv.findChildViewUnder(e.x, e.y)

if (child != null && gestureDetector.onTouchEvent(e))
onTouchCallback.onItemClick(child, rv.getChildLayoutPosition(child), e)


return false


override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean)



override fun onTouchEvent(rv: RecyclerView, e: MotionEvent)



//endregion

interface ItemTouchListener
fun onItemClick(view: View, pos: Int, e: MotionEvent)
fun onItemLongClick(view: View, pos: Int, e: MotionEvent)


companion object
fun isViewClicked(container: View, @IdRes viewId: Int, e: MotionEvent): Boolean
val view = container.findViewById<View>(viewId)

val rect = Rect()
view.getGlobalVisibleRect(rect)

return view.isVisible && rect.contains(e.rawX.toInt(), e.rawY.toInt())












share|improve this question















I'm detecting clicks in my recyclerview using the OnItemTouchListener class below. Unfortunately, this does not work well when using a DrawerLayout. If I swipe to open the DrawerLayout/NavigationView, my OnItemTouchListener gets this event too and executes the onLongClick action.



This does not happen if I use the ViewHolders' View.OnLongClick. What's the little secret, Views' OnLongClickListener checks before firing an LongClick-event to detect that the drag-action is not a long click, but a gesture to open the drawer?



class OnItemTouchListener(context: Context, recyclerView: RecyclerView, private var onTouchCallback: ItemTouchListener) : RecyclerView.OnItemTouchListener 

//region Variables

private val gestureDetector: GestureDetector

//endregion

init
gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener()
override fun onSingleTapUp(e: MotionEvent?): Boolean
return true


override fun onLongPress(e: MotionEvent?)
val child: View? = recyclerView.findChildViewUnder(e!!.x, e.y)

if (child != null)
onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), e)


super.onLongPress(e)

)


//region TouchHandler

override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean
val child = rv.findChildViewUnder(e.x, e.y)

if (child != null && gestureDetector.onTouchEvent(e))
onTouchCallback.onItemClick(child, rv.getChildLayoutPosition(child), e)


return false


override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean)



override fun onTouchEvent(rv: RecyclerView, e: MotionEvent)



//endregion

interface ItemTouchListener
fun onItemClick(view: View, pos: Int, e: MotionEvent)
fun onItemLongClick(view: View, pos: Int, e: MotionEvent)


companion object
fun isViewClicked(container: View, @IdRes viewId: Int, e: MotionEvent): Boolean
val view = container.findViewById<View>(viewId)

val rect = Rect()
view.getGlobalVisibleRect(rect)

return view.isVisible && rect.contains(e.rawX.toInt(), e.rawY.toInt())









android android-recyclerview kotlin android-view android-navigation-drawer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 10 at 14:49

























asked Nov 9 at 21:53









the_dani

6511721




6511721











  • You can avoid calling super in long press to notify system about you've already consumed long press.
    – Jeel Vankhede
    Nov 10 at 14:46











  • @JeelVankhede This method has no return type. The problem is that I do not want gestureDetector to detect a LongPress if I'm swiping to open the drawer...
    – the_dani
    Nov 10 at 14:48
















  • You can avoid calling super in long press to notify system about you've already consumed long press.
    – Jeel Vankhede
    Nov 10 at 14:46











  • @JeelVankhede This method has no return type. The problem is that I do not want gestureDetector to detect a LongPress if I'm swiping to open the drawer...
    – the_dani
    Nov 10 at 14:48















You can avoid calling super in long press to notify system about you've already consumed long press.
– Jeel Vankhede
Nov 10 at 14:46





You can avoid calling super in long press to notify system about you've already consumed long press.
– Jeel Vankhede
Nov 10 at 14:46













@JeelVankhede This method has no return type. The problem is that I do not want gestureDetector to detect a LongPress if I'm swiping to open the drawer...
– the_dani
Nov 10 at 14:48




@JeelVankhede This method has no return type. The problem is that I do not want gestureDetector to detect a LongPress if I'm swiping to open the drawer...
– the_dani
Nov 10 at 14:48












1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










I solved it the following way:



gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() 
private val MIN_SWIPE_DISTANCE: Int = 50
private lateinit var downMotionEvent: MotionEvent

override fun onDown(e: MotionEvent?): Boolean
e?.let downMotionEvent = it

return super.onDown(e)


override fun onSingleTapUp(e: MotionEvent?): Boolean
return true


override fun onLongPress(e: MotionEvent?)
e?.let
val child: View? = recyclerView.findChildViewUnder(it.x, it.y)

if (child != null && !isGestureSwipe(it))
onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), it)



super.onLongPress(e)


fun isGestureSwipe(e: MotionEvent): Boolean
return downMotionEvent.x - e.x <= MIN_SWIPE_DISTANCE

)





share|improve this answer




















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53233700%2fontouchlisterner-shall-not-interpret-swipes-do-open-drawerlayout-as-long-click%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    I solved it the following way:



    gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() 
    private val MIN_SWIPE_DISTANCE: Int = 50
    private lateinit var downMotionEvent: MotionEvent

    override fun onDown(e: MotionEvent?): Boolean
    e?.let downMotionEvent = it

    return super.onDown(e)


    override fun onSingleTapUp(e: MotionEvent?): Boolean
    return true


    override fun onLongPress(e: MotionEvent?)
    e?.let
    val child: View? = recyclerView.findChildViewUnder(it.x, it.y)

    if (child != null && !isGestureSwipe(it))
    onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), it)



    super.onLongPress(e)


    fun isGestureSwipe(e: MotionEvent): Boolean
    return downMotionEvent.x - e.x <= MIN_SWIPE_DISTANCE

    )





    share|improve this answer
























      up vote
      2
      down vote



      accepted










      I solved it the following way:



      gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() 
      private val MIN_SWIPE_DISTANCE: Int = 50
      private lateinit var downMotionEvent: MotionEvent

      override fun onDown(e: MotionEvent?): Boolean
      e?.let downMotionEvent = it

      return super.onDown(e)


      override fun onSingleTapUp(e: MotionEvent?): Boolean
      return true


      override fun onLongPress(e: MotionEvent?)
      e?.let
      val child: View? = recyclerView.findChildViewUnder(it.x, it.y)

      if (child != null && !isGestureSwipe(it))
      onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), it)



      super.onLongPress(e)


      fun isGestureSwipe(e: MotionEvent): Boolean
      return downMotionEvent.x - e.x <= MIN_SWIPE_DISTANCE

      )





      share|improve this answer






















        up vote
        2
        down vote



        accepted







        up vote
        2
        down vote



        accepted






        I solved it the following way:



        gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() 
        private val MIN_SWIPE_DISTANCE: Int = 50
        private lateinit var downMotionEvent: MotionEvent

        override fun onDown(e: MotionEvent?): Boolean
        e?.let downMotionEvent = it

        return super.onDown(e)


        override fun onSingleTapUp(e: MotionEvent?): Boolean
        return true


        override fun onLongPress(e: MotionEvent?)
        e?.let
        val child: View? = recyclerView.findChildViewUnder(it.x, it.y)

        if (child != null && !isGestureSwipe(it))
        onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), it)



        super.onLongPress(e)


        fun isGestureSwipe(e: MotionEvent): Boolean
        return downMotionEvent.x - e.x <= MIN_SWIPE_DISTANCE

        )





        share|improve this answer












        I solved it the following way:



        gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() 
        private val MIN_SWIPE_DISTANCE: Int = 50
        private lateinit var downMotionEvent: MotionEvent

        override fun onDown(e: MotionEvent?): Boolean
        e?.let downMotionEvent = it

        return super.onDown(e)


        override fun onSingleTapUp(e: MotionEvent?): Boolean
        return true


        override fun onLongPress(e: MotionEvent?)
        e?.let
        val child: View? = recyclerView.findChildViewUnder(it.x, it.y)

        if (child != null && !isGestureSwipe(it))
        onTouchCallback.onItemLongClick(child, recyclerView.getChildLayoutPosition(child), it)



        super.onLongPress(e)


        fun isGestureSwipe(e: MotionEvent): Boolean
        return downMotionEvent.x - e.x <= MIN_SWIPE_DISTANCE

        )






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 13 at 18:39









        the_dani

        6511721




        6511721



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53233700%2fontouchlisterner-shall-not-interpret-swipes-do-open-drawerlayout-as-long-click%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

            Syphilis

            Darth Vader #20