我想为我的 RecyclerView
的 GridLayoutManager
添加动画效果。默认情况下,以3列的网格形式显示项目列表,用户可以选择显示更多或更少的列。
我希望RecyclerView
中的 views
移动/缩放到它们的新位置,但我不知道如何实现。
我最终想要的
- 通过扩展/收缩触摸手势来允许缩放网格=>我知道如何做到这一点
- 动画改变
LayoutManager
有人知道如何动画改变 LayoutManager
吗?
我想为我的 RecyclerView
的 GridLayoutManager
添加动画效果。默认情况下,以3列的网格形式显示项目列表,用户可以选择显示更多或更少的列。
我希望RecyclerView
中的 views
移动/缩放到它们的新位置,但我不知道如何实现。
我最终想要的
LayoutManager
有人知道如何动画改变 LayoutManager
吗?
这里的灵感来源是Google Photos应用程序和索尼库应用程序。
基本上有两种方法:
使用 setSpanCount(int) 修改GridLayoutManager的spancount
设置一个非常高的span count( ~100),使用 SpanSizeLookUp 来动态更改每个项目的spanSize。
这不是一个完整的解决方案,而是为同样问题提供的2小时解决方案。显然,您可以改进提到的所有点 : )。 我希望继续更新示例,因为这种视图一直吸引着我。 不要将此视为最终解决方案,而只是实现此方法的特定方式。如果您使用StaggerredLayoutManager,则可以轻松避免项目之间的空白。
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;
}
notifyItemRangeChanged
就可以正确启动动画...唯一的缺点是(但我在问题中没有要求更多),你只能使用 GridLayoutManager
,不能在不同的 LayoutManager
之间切换...虽然,如果你想要,GridLayoutManager
也支持1列,因此至少也可以用作 LinearLayoutManager
... - prom85我和你遇到了同样的问题,到目前为止,我还没有找到一个好的解决方案。
在GridLayoutManager中简单更改列数似乎有些奇怪,所以目前我使用动画来淡入淡出整个布局。类似这样:
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);
}
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;
}
});
setSpanCount
,接着调用notifyDatasetChanged()
? - Droidekas