我正在尝试用新的 RecyclerView(使用 GridLayoutManager)替换我的 GridView,但它似乎不能很好地处理 gridLayoutAnimation(ClassCastException: LayoutAnimationController$AnimationParameters cannot be cast to GridLayoutAnimationController$AnimationParameters
)。它适用于常规布局动画,但由于它是网格,因此在平板电脑上完成需要很长时间。
我想要完成的是类似于Hierarchical Timing。如果您查看示例视频,它会显示布局动画从左上角到右下角对角线。常规布局动画将逐行执行动画,因此在更大的网格(例如平板电脑)上完成需要花费太多时间。我也尝试过探索 ItemAnimator,但这只会像“不要”示例中那样同时在所有单元格上运行动画。
有没有办法在 RecyclerView 中完成这个网格布局动画?
这是 gridview_layout_animation.xml:
<!-- replace gridLayoutAnimation with layoutAnimation and -->
<!-- replace column- and rowDelay with delay for RecyclerView -->
<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:columnDelay="15%"
android:rowDelay="15%"
android:animation="@anim/grow_in"
android:animationOrder="normal"
android:direction="top_to_bottom|left_to_right"
android:interpolator="@android:interpolator/linear"
/>
这是动画grow_in.xml:
<set android:shareInterpolator="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="@android:interpolator/decelerate_quint"
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="true"
android:duration="400"
android:startOffset="200"
/>
</set>
编辑:根据 Galaxas0 的回答,这里有一个解决方案,只需要您使用扩展的自定义视图RecyclerView
。基本上只覆盖attachLayoutAnimationParameters()
方法。使用<gridLayoutAnimation>
它就像使用 GridView 一样。
public class GridRecyclerView extends RecyclerView {
public GridRecyclerView(Context context) {
super(context);
}
public GridRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GridRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void setLayoutManager(LayoutManager layout) {
if (layout instanceof GridLayoutManager){
super.setLayoutManager(layout);
} else {
throw new ClassCastException("You should only use a GridLayoutManager with GridRecyclerView.");
}
}
@Override
protected void attachLayoutAnimationParameters(View child, ViewGroup.LayoutParams params, int index, int count) {
if (getAdapter() != null && getLayoutManager() instanceof GridLayoutManager){
GridLayoutAnimationController.AnimationParameters animationParams =
(GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters;
if (animationParams == null) {
animationParams = new GridLayoutAnimationController.AnimationParameters();
params.layoutAnimationParameters = animationParams;
}
int columns = ((GridLayoutManager) getLayoutManager()).getSpanCount();
animationParams.count = count;
animationParams.index = index;
animationParams.columnsCount = columns;
animationParams.rowsCount = count / columns;
final int invertedIndex = count - 1 - index;
animationParams.column = columns - 1 - (invertedIndex % columns);
animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns;
} else {
super.attachLayoutAnimationParameters(child, params, index, count);
}
}
}