I want to animate the change of my RecyclerView
s GridLayoutManager
. I defaulty show a list of items in a grid with 3 columns and the user can selec
You can do this with "gesture detector" see the sample tutorial here http://wiki.workassis.com/pinch-zoom-in-recycler-view/ In this tutorial we will fetch images from gallery and show them in a grid layout in recycler view. You will be able to change layout on pinch gesture. Following are the screen shots of different layouts.
mScaleGestureDetector = new ScaleGestureDetector(this, new ScaleGestureDetector.SimpleOnScaleGestureListener() {
@Override
public boolean onScale(ScaleGestureDetector detector) {
if (detector.getCurrentSpan() > 200 && detector.getTimeDelta() > 200) {
if (detector.getCurrentSpan() - detector.getPreviousSpan() < -1) {
if (mCurrentLayoutManager == mGridLayoutManager1) {
mCurrentLayoutManager = mGridLayoutManager2;
mRvPhotos.setLayoutManager(mGridLayoutManager2);
return true;
} else if (mCurrentLayoutManager == mGridLayoutManager2) {
mCurrentLayoutManager = mGridLayoutManager3;
mRvPhotos.setLayoutManager(mGridLayoutManager3);
return true;
}
} else if(detector.getCurrentSpan() - detector.getPreviousSpan() > 1) {
if (mCurrentLayoutManager == mGridLayoutManager3) {
mCurrentLayoutManager = mGridLayoutManager2;
mRvPhotos.setLayoutManager(mGridLayoutManager2);
return true;
} else if (mCurrentLayoutManager == mGridLayoutManager2) {
mCurrentLayoutManager = mGridLayoutManager1;
mRvPhotos.setLayoutManager(mGridLayoutManager1);
return true;
}
}
}
return false;
}
});
The source of inspiration here would be the Google Photos app,the stock Sony Gallery app
There are basically 2 approaches you can go with:
You modify the spancount of the GridLayoutManager using setSpanCount(int)
You set a very high span count(~100) use the SpanSizeLookUp to change the per item spanSize on the fly.
This is not a complete solution but a 2 hour solution for the same.You can obviously improve on all the points mentioned :). I hope to keep updating the sample since this kind of views have always fascinated me. Do not view this as the final solution but just a particular way of achieving this approach. If you were to use a StaggerredLayoutManager instead,you could easily avoid blank spaces between items.
public int calculateRange() {
int start = ((GridLayoutManager) grv.getLayoutManager()).findFirstVisibleItemPosition();
int end = ((GridLayoutManager) grv.getLayoutManager()).findLastVisibleItemPosition();
if (start < 0)
start = 0;
if (end < 0)
end = getItemCount();
return end - start;
}
I deal with the same problem as you, and so far I have not found a good solution.
Simple change of columns number in GridLayoutManager seems weird so for now I use animation to fade out/in entire layout. Something like this:
private void animateRecyclerLayoutChange(final int layoutSpanCount) {
Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new DecelerateInterpolator());
fadeOut.setDuration(400);
fadeOut.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
productsRecyclerLayoutManager.setSpanCount(layoutSpanCount);
productsRecyclerLayoutManager.requestLayout();
Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new AccelerateInterpolator());
fadeIn.setDuration(400);
productsRecycler.startAnimation(fadeIn);
}
});
productsRecycler.startAnimation(fadeOut);
}
If you combine fade out/in animation with scaling each visible item, It will be a decent animation for GridLayoutManager changes.