I'm trying to make the items within a RecyclerView scroll along a path, specifically a curve. At the left and right edge of the screen the offset is 0, and in the middle of the screen the offset is 100% for example. I am attempting to achieve this by setting the Y translation of each view. Currently I am doing this in an OnScrollListener attached to the RecyclerView. This mostly works OK, but there are occasions where the OnScrollListener isn't invoked so the translation resets to 0. These occasions include when adding or removing an item from the RecyclerViews adapter.
Is there a better place to attempt to achieve this effect? I have also looked into using my own LayoutManager and overriding OnLayoutChildren, but again this doesn't work in all cases and isn't called when scrolling.
Related
This is a question regarding the use of Android Transition API.
I am trying to animate the height change of a list, just like a dropdown menu.
I tried 2 approaches
Use a RecyclerView and animates its height change
Use a ScrollView > LinearLayout hierarchy and animates ScrollView's height.
The 2nd approach works perfectly.
But the 1st approach has a serious glitch - when the collapse transition starts, items disappear immediately.
By looking at the below GIF you can observe clearly the difference:
To be exact, items' visibility changes at the moment I change RecyclerView's LayoutParams, without waiting for the transition to finish, whatever it is expanding or collapsing
Code
I have created a minimal project on Github.
If you just want to look at the code, here is the MainActivity.
Question
Is it possible to achieve ScrollView's effect with a RecyclerView?
If yes, how?
My Idea is to do the transition of all the recycler view rows individual rather than the whole RecyclerView:
So when collapsing iterate through each ROW of a RecyclerView and do a transition. Remember to check for null if some rows are recycled they may return null. So after that collapse the whole recyclerView.
And like wise for the expanding do the same for the views.
This issue is cause by RecyclerView has many views with it but Scroll View has only one View nested in it.
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 am creating a custom scroll inside RecyclerView and I did most of the work already but now I came to hopefully one of the last problems.
On scrolling, I am expanding/collapsing rows as they move up or down. It works fine until I reach the bottom of the list. Two items remain in their normal state because I can no longer scroll down and therefore they will not expand.
My question is, how can I scroll under the recyclerView when I reach the bottom? Do I need to implement onTouch listener and do the work from there? Or is there something in RecyclerView that can help me create the underscroll?
You should be able to expand them in onOverScrolled, as that will be called at the correct time to trigger their expansion.
I have been looking for a long time for a Android RecyclerView onLoad animation
but until now I have not found anything really helpful.
What I want is to have an animation when the RecyclerView loads and displays the cells animated.
But I want to have that animation just when the RecyclerView loads and not when the cells are loaded by the ViewHolder.
Because when the cells are loaded by the ViewHolder the RecyclerView animates the cells while scrolling and so on...
So I don't want no animation while scrolling anymore.
And some guys will know that the effect I would like to implement is
a standard animation effect the TableView of iOS supports.
I have found a tutorial where is exactly done what I would like to do.
The last example is what I mean.
So all solutions I have found were similar to that one
Has anyone an idea?
Or is the way I would like to animate the cells "not Android standard like"?
kind regards
Well one way to do this is to make sure that you are animating the entire recyclerview when your activity / fragment is ready and displayed on screen. So instead of animating each individual item in the recyclerview, you set an animation on the recyclerview as a whole to "fly" in for example, by animating the TranslateY element of the recyclerview.
I am trying to make a horizontally scrolling grid. It has two rows. The second row is offset (by half the width of one item, but that is trivial to calculate and doesn't matter here).
I am currently using RecyclerView and the GridLayoutManager from https://github.com/antoniolg/RecyclerViewExtensions/tree/master/library/src/main/java/com/antonioleiva/recyclerviewextensions
However, the offsetting is proving extremely difficult.
It should end up looking like
Does anybody have any suggestions for making the second row staggered like in the picture above?
Use StaggeredGridLayoutManager with an ItemDecoration which adds the offset to the item at adapter position 0. You'll get the desired output. (via getItemOffsets).
Alternatively, instead of an ItemDecoration, when onBind is called, you can set the first item's width such that it will include gap on left.
If your data set changes, don't call notifyDataSetChanged which will reset the historical calculations in SGLM. Instead, use detailed notify events like notifyItemRangeInserted so that SGLM will be able to recalculate layout without resetting positions.
I don't know if you're still working on this, but my approach would be to render the items 2 at a time (top/bottom) with the appropriate offset, and then play with your horizontal margins (set them to negative) to create the overlap between item 2 and 3, etc.
You would have to tie OnTouchListeners to the individual items being rendered, not the RecyclerView entries.