I have a ViewPager2 of vertical orientation with each item consisting of Recyclerview. Sometime on fast scrolling, the content of the recylcerview is not scrolled rather page change is triggered on ViewPager2.
When this issue occurs, I am using NestedScrollableHost provided by Android Developer site doesn't get a callback inside onInterceptTouchEvent method.
Please suggest.
Related
I have nested ViewPagers and RecyclerViews as depicted in the image:
Requirements:
The first level ViewPager1 swipes from left to right. It uses FragmentStatePagerAdapter.
The first level RecyclerView1 scrolls vertically.
The second level ViewPager2 does not swipe - the swipe motion is controlled by a TabLayout. It uses a custom PagerAdapter that returns a View as a page.
The second level RecyclerView does not scroll - it simply wraps a list of dynamic items
What I have working so far:
The first level ViewPager1 and RecyclerView1 works as intended.
The ViewPager2 does not show because its height is defined as "wrap_content"
The ViewPager2/RecyclerView2 prevents RecyclerView1 to scroll up/down.
What I have tried:
Setting RecyclerView1.setNestedScrollingEnabled(false) stops it from passing the onTouch event to its children, but because the ViewPager2/RecyclerView2 wraps its content, it does not know what the size it needs to scroll.
Setting the ViewPager2 to a fixed height solves the scrolling problem. But because it is a fixed height, the content of RecyclerView2 is cut off.
Overriding OnMeasure as described here makes ViewPager2's content wrap, perfectly, but the scrolling no longer work again. I assume it is because OnMeasure is called "after" the View has already been attached?
So basically I need help on how to get the content to wrap but in such a way that RecyclerView 1 knows what the height is so that it can scroll.
EDIT
It turns out I was totally off base with point 3. The OnMeasure workaround DOES work as intended and the scrolling problem is NOT caused by recyclerView not knowing the height. It in fact does. The reason why it doesn't scroll is due to multiple nested scrollable view groups. I found this out by putting Log.i on onTouchEvent() and onInterceptTouchEvent() on all the scrollable view groups. Some surface of the views work, but if the surface has another scrollable child, it starts to cause problems.
Setting RecyclerView2.setNestedScrollingEnabled(false) fixed the vertical scrolling. However, now, the ViewPager2's touch behaviour is interfering with ViewPager1's
On closer inspection, ViewPager1 intercepts touch event when hitting non-scrollable surface, causing the ViewPager1 to call its onTouchEvent() to scroll left and right. However, if I start the touch event over a the ViewPager2's surface, ViewPager1 never intercept and it never handles the swipe left to right.
Unlike a RecyclerView, there is no simple method to disable nestedScrolling. So I tried disabling ViewPager2, but that didn't work and caused the inside views such as buttons not clickable.
I tried to return false in ViewPager2's OnTouchEvent so that it bubbles up the chain, but still, the ViewPager1's OnTouchEvent is never fired.
So I'm stuck again, how do I pass the touch event to the parent when the parent did not intercept the event when it should have. Again, I'm assuming, and again I might be off-base, that ViewPager1 might not intercept because ViewPager2 has requested a disallowInterceptTouchEvent() somewhere in its code? I just don't know where or how to begin to fix this problem.
I've updated my RecyclerView version to 26.0.1 and I have pagination implemented with RecyclerView, so when I reach bottom of the list I see ProgressBar and load more data to display, then notify inserted indexes
So with new 26.0.1 RecyclerView version there's inertia saved from scrolling. So when I swipe down fast and reach bottom I see ProgressBar, but after new data inserted RecyclerView keeps scrolling down
I know that's it inertia because if I swipe slowly, it doesn't scroll down after new data being inserted
Question: how to disable this inertia swiping?
P.S. My RecyclerView is inside NestedScrollView
Sorry for late response, but I faced with the same issue.
I had a NestedScrollView containing multiple items including RecyclerView.
I noticed that when LOADING state is shown, everything scrolls without any inertia, but once I make recyclerView visible, inertia appears. That code helped me:
recyclerView.isNestedScrollingEnabled = false
It helped for androidX RecylerView widget.
Ran into the same issue, a RecyclerView with infinite scrolling on API 26. Solved it by just adding this code to the overriden onScrolled event I was already using to load subsequent pages of data. I placed it after the super.onScrolled() call and before my infinite page loading trigger.
if (!recyclerView.canScrollVertically(1)) {
recyclerView.stopScroll();
}
This detects whether the RecyclerView can no longer scroll downwards (1 for down, -1 for up), and uses the built-in method to halt scrolling.
I am developing and application that will have to implement the swipe-to-refresh pattern described here. Looking at the android docs here, it is stated that:
You enable this behavior by adding the widget to your layout file as the parent of a ListView or GridView, and implementing the refresh behavior that gets invoked when the user swipes.
Well the issue is that I do not plan on having a ListView or GridView to layout my data, I am using cards (android.support.design.CardView) and I am planning on having a scrolling list of cards that the end user can swipe to refresh.
Can I still use the SwipeToRefreshLayout as described in the tutorial with my cards, or does it force me to use ListViews or GridViews to display my data?
Well as the documentation says that
The SwipeRefreshLayout should be used whenever the user can refresh
the contents of a view via a vertical swipe gesture.
This layout should be made the parent of the view that will be
refreshed as a result of the gesture and can only support one direct
child.
It does not mention that the view must be a ListView or a RecyclerView.
Also as seen in those questions:
SwiperefreshLayout in Android
Android SwipeRefreshLayout how to implement canChildScrollUp if child is not a ListView or ScrollView
Both of them have implemented a SwipeRefreshLayout with LinearLayout as the child View. So yes it will work with the view either being a CardView or a ScrollView.
Hope it helps!!!
Simple question - how to disable recyclerview scrolling while swiping its item? I created OnTouchListener inside recyclerView item view holder, but it catches swipe events only if user makes straight horizontal line. Otherwise recycler list is scrolling. Any ideas?
I am not using ItemTouchHelper because it doesnt quite do what I want. I solved this by checking the source to it and finding the call to:
getParent().requestDisallowInterceptTouchEvent(true)
Call that when you determine the user has started swiping (i.e., moved more than a few pixels). Then don't forget it to call it again with false when the swipe is done.
I'm facing the opposite problem. If you are using the ItemTouchHelper, do this
mItemTouchHelper.startSwipe(myViewHolder);
This would force the swipe instead of the scroll.
I have read on the github page for Android-ParallaxViewPager about implementing it using ScrollView but I didn't understand what it actually meant! :(
This is what given on the github page -
How to implement? see below.
1. Change ListView in NotBoringActionBar to ViewPager.
2. Make ListView or ScrollView of Fragment in ViewPager.
3. Make Interface that Activity can get a Listener when you use OnScroll() in ListView or ScrollView.
4. Make Interface which is available to scroll when some events is happened in ListView or ScrollView.
From now on, you can fix scrollY value in ListView wherever the pages are swiped through the interface you've just made.
Can anyone help me with this? I'm sure I'm not the only trying to get this working with ScrollView.
In its code kmshack has used an interface with onScroll() method accepting AbsListView view as a parameter.(for handling the scroll events inside ListView)
Does this mean that for ScrollView the onScroll() method should accept the ScrollView for handling the scroll events inside ScrollView?
Or a method has to be defined for handling the scroll events?
I'm confused! Please help me.