I'm trying to play with Parallax and getting some weird bugs, wondering if anyone can add some input to it. The only app I've seen implement parallax effectively is soundcloud. It's quite subtle, but each item has an image background and it has he parallax effect as you scroll.
I've created a custom RecyclerView to handle this, here is what I have so far:
public class ParallaxScrollListener extends RecyclerView.OnScrollListener {
private float scrollSpeed = 0.5f;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
int firstVisible = layoutManager.findFirstVisibleItemPosition();
int visibleCount = Math.abs(firstVisible - layoutManager.findLastVisibleItemPosition());
Matrix imageMatrix;
float tempSpeed = -100;
if (dy > 0) {
tempSpeed = scrollSpeed;
} else if (dy < 0) {
tempSpeed = -scrollSpeed;
}
for (int i = firstVisible; i < (firstVisible + visibleCount); i++) {
ImageView imageView = ((MyClass.MyAdapter.MyViewHolder) recyclerView.getLayoutManager().findViewByPosition(i).getTag()).image;
if (imageView != null) {
imageMatrix = imageView.getImageMatrix();
imageMatrix.postTranslate(0, tempSpeed);
imageView.setImageMatrix(imageMatrix);
imageView.invalidate();
}
}
}
In my RecyclerView
Adapter's onBindView
I have the following as well:
Matrix matrix = viewHolder.image.getImageMatrix();
matrix.postTranslate(0, 0);
viewHolder.image.setImageMatrix(matrix);
viewHolder.itemView.setTag(viewHolder);
Finally inside the onViewRecycled
method I have the following:
@Override
public void onViewRecycled(MyViewHolder viewHolder) {
super.onViewRecycled(viewHolder);
if (viewHolder.image != null) {
viewHolder.image.setScaleType(ImageView.ScaleType.MATRIX);
Matrix matrix = viewHolder.image.getImageMatrix();
// this is set manually to show to the center
matrix.reset();
viewHolder.image.setImageMatrix(matrix);
}
}
I been working with this code on Github to get the idea
So the parallax works, but but views in my RecyclerView move as well. I have a CardView beneath the image and it moves, creating big gaps between each item. Scrolling is what causes this, the more the scroll up and down the bigger the gaps get, and the images get smaller as the parallax moves them out of their bounds.
I've tried messing with the numbers like scrollSpeed in the OnScrollListener
but while it reduces the bug it also reduces the parallax.
Has anyone got any ideas on how I can achieve a bug free parallax effect on each item in my RecyclerView
? I feel like I'm getting somewhere with this but it's still very buggy and I don't know what the next step is.
P.s I've tried looking at 3rd party libraries but they all seem to only use header parallax like the CoordinatorLayout, I haven't found any that do it just on each item in a list.
I'm hoping this question gets a good discussion going even if I don't solve my problem because Parallax seems to be underused in Android and there's very little around about it.
Thanks for you time, appreciate any help.
onBindVH
? – Buoyage