Ich versuche, meine GridView durch die neue RecyclerView zu ersetzen (mit GridLayoutManager), aber es scheint, dass es nicht gut mit GridLayoutAnimation (ClassCastException: LayoutAnimationController$AnimationParameters cannot be cast to GridLayoutAnimationController$AnimationParameters
) zurecht kommt. Es funktioniert mit einer normalen Layoutanimation, aber da es sich um ein Raster handelt, dauert die Fertigstellung auf Tablets zu lange.Wie verwende ich eine GridLayoutAnimation in einem RecyclerView?
Was ich zu erreichen versuche ist ähnlich wie Hierarchical Timing. Wenn Sie sich das Beispielvideo ansehen, wird die Layoutanimation von oben links nach unten - rechts diagonal angezeigt. Eine reguläre Layoutanimation würde die Animation Reihe um Reihe ausführen, wodurch es zu viel Zeit erfordert, um auf größeren Gittern (z. B. Tablets) zu vervollständigen. Ich habe auch versucht, ItemAnimator zu erkunden, aber das würde nur die Animation auf allen Zellen simultan wie im Beispiel "Do not" ausführen.
Gibt es eine Möglichkeit, diese Rasterlayout-Animation in einem RecyclerView zu erstellen?
Dies ist 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"
/>
Und das ist die grow_in.xml Animation:
<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>
EDIT: Basierend auf Galaxas0 Antwort ist here ein Lösung, die nur erfordert, dass Sie eine benutzerdefinierte Ansicht verwenden, die RecyclerView
erweitert. Im Grunde nur überschreiben die attachLayoutAnimationParameters()
Methode. Damit funktioniert <gridLayoutAnimation>
wie bei 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);
}
}
}
Könnten Sie bitte erklären, wie? Ich habe versucht, es mit dem Standard-ItemAnimator sowie das Herunterladen von Beispielen für verschiedene [ItemAnimators] (https://github.com/gabrielemariotti/RecyclerViewItemAnimators/tree/master/library/src/main/java/it/gmariotti/recyclerview/itemanimator), aber ich kann nicht auf die Animation, die ich suche, scheinen. – Musenkishi
Haben Sie sichergestellt, dass Sie 'notifyDataSetChanged()' nicht verwenden und stattdessen 'notifyItemRangeAdded()' und 'notifyItemRangeRemoved()' 'verwenden? Dies sollte immer die erste Lade-Animation auslösen. –
Ja, ich habe versucht, 'notifyItemRangeAdded()' zu verwenden, aber wie ich oben beschrieben habe, gibt es mir nicht das gewünschte Verhalten. 'notifyItemRangeAdded()' wird die Animation in der ersten Zeile ausführen und ** nicht ** in der zweiten Zeile, bis alle Zellen in der ersten Zeile mit ihrer Animation begonnen haben. Die Animation, die ich von einem ' erhalten könnte, könnte diagonal über die Zeilen gehen, was bedeutet, dass sie mehrere Zeilen gleichzeitig animieren könnte. Im Wesentlichen werden alle Zellen im Gitter in einer Welle von oben links nach rechts unten angezeigt. –
Musenkishi