I got a Recyclerview and a EditText in my layout.
When I click outside the EditText (i.e clicks on the Recyclerview) I want the Recyclerview to get focus and the EditText view to loose focus. I cant get this to work. If I put a empty FrameLayout above the Recyclerview everything works as expected but I cant scroll the Recyclerview. Why cant I set the Recyclerview to be clickable and focusable?
I set these attributes in my layout xml
android:clickable="true"
android:focusable="auto"
android:focusableInTouchMode="true"
android:focusedByDefault="true"
on my Recyclerview/FrameLayout.
The reason your xml tags have no effect is how Android handles clicks. Every event goes through the view hierarchy of the layout. First, the very top level parent of the layout receives the event. If the top level layout does not handle the event, then it gets passed to the child under it and so on.
In your case the touch event is first sent to the FrameLayout and since it is handled, the event doesn't reach the RecyclerView and therefore you cannot scroll.
The correct way to handle touch is to set onTouchListener on both the RecyclerView and the child view. The onTouch on the RecyclerView is called first. You handle all your analyzing there (you can check x and y and also see if the touch falls inside a child view. you can also change the focus of each view dynamically).
If you don't want the child to also handle the touch return true;. Otherwise return false; and the touch event will trigger the onTouchListener of the child view.
Related
My fragment view implements a touch listener to listen to various gestures but my horizontally fashioned recyclerview consumes any gesture performed over it.
Basically I want to listen to vertical swipe when performed over recyclerview but I never receive callback in fragment view's gesture detector.
I was able to get a workaround for it. I had to subclass ViewGroup and override onInterceptTouchEvent and handle things using MotionEvent.{action_type}. Then I replaced the fragment view's parent view group with this custom view group inside xml layout.
So in nutshell, if I detect it as a vertical swipe I return true in my onInterceptTouchEvent otherwise false. If its false, the touch event is passed onto the child views for handling. Works perfect.
I have a RecyclerView (which scrolls vertically) whose ViewHolders contain RecyclerViews that scroll horizontally. When you tap on an item in horizontal (nested) RecyclerViews, I want the entire row to have the ripple effect.
To do this, I've been trying to override the touch events and get them to get passed up the view stack (by returning false in touch event handlers). This works on views other than RecyclerViews, but it isn't having the desired effect for RecyclerViews.
How do I correctly pass the tap event on a RecyclerView up to the enclosing view?
Haven't found a way to pass the click event up to a recycler view's parent view, but the important thing was getting the ripple effect to happen – which I was able to do. So when a view holder's itemView get's tapped, I do this:
val background = itemView.background
if (background is RippleDrawable) {
background.setState(intArrayOf(android.R.attr.state_pressed, android.R.attr.state_enabled))
}
Which manually triggers the ripple effect.
I have a vertical RecyclerView and inside every item a custom view with own horizontal scroll and scale. When I try to scroll view inside item I get scroll conflict RecyclerView interrupts touch event and tries to move the list.
How can I restrict RecyclerView to handle horizontal swipe event?
I tried to interrupt event via RecyclerView.OnItemTouchListener and pass them directly to my custom view. That almost works but sometimes I get wrong events and scroll in the custom view does not work.
Has someone else faced this problem?
Try use simple OnTouchListener instead OnItemTouchListener
I have a ScrollView, inside that I have LinearLayout with 4 children. My problem is that my ScrollView consumes events and because of that I am not able to long press on my child views. I tried setting setLongClickable(false) but it is of no use, if I intercept touch events I'm not able to scroll my ScrollView.
Normally Android uses a long press to begin a drag in cases like these since it helps disambiguate when the user intends to longPress an item vs. scroll the item's container. But if you have an unambiguous signal when the user begins longpress an item, try getParent().requestDisallowInterceptTouchEvent(true) from the view when you know the user is beginning a press. This will prevent the ScrollView from intercepting touch events until the end of the current gesture.(check this link https://developer.android.com/reference/android/view/ViewParent.html#requestDisallowInterceptTouchEvent%28boolean%29)
I have a ListView inside a ScrollView. I know I can intercept the touch events using the onInterceptTouchEvent method in the ScrollView. But once the child, i.e. ListView, starts consuming the touch event, onInterceptTouchEvent is not call. My problem is how can I transfer the touch event back to parent(i.e. ScrollView) once the ListView scroll has reached top. I want the scroll to be in continuation.
Suppose I'm scrolling the ListView and have reached the top of the ListView I want the scroll to continue so that I can scroll the parent, i.e. ScrollView. How can I achieve this?
You can check whether you are at the top of the listview, then return false from the touch event.