GridView を新しい RecyclerView (GridLayoutManager を使用) に置き換えようとしていますが、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);
}
}
}