OnTouchListerner shall not interpret swipes do open DrawerLayout as Long Click
up vote
2
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())
}
}
}
android android-recyclerview kotlin android-view android-navigation-drawer
This question has an open bounty worth +50
reputation from the_dani ending in 6 days.
The question is widely applicable to a large audience. A detailed canonical answer is required to address all the concerns.
add a comment |
up vote
2
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())
}
}
}
android android-recyclerview kotlin android-view android-navigation-drawer
This question has an open bounty worth +50
reputation from the_dani ending in 6 days.
The question is widely applicable to a large audience. A detailed canonical answer is required to address all the concerns.
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
add a comment |
up vote
2
down vote
favorite
up vote
2
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())
}
}
}
android android-recyclerview kotlin android-view android-navigation-drawer
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
android android-recyclerview kotlin android-view android-navigation-drawer
edited Nov 10 at 14:49
asked Nov 9 at 21:53
the_dani
6211721
6211721
This question has an open bounty worth +50
reputation from the_dani ending in 6 days.
The question is widely applicable to a large audience. A detailed canonical answer is required to address all the concerns.
This question has an open bounty worth +50
reputation from the_dani ending in 6 days.
The question is widely applicable to a large audience. A detailed canonical answer is required to address all the concerns.
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
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
}
})
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
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
}
})
add a comment |
up vote
0
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
}
})
add a comment |
up vote
0
down vote
accepted
up vote
0
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
}
})
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
}
})
answered 11 hours ago
the_dani
6211721
6211721
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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