Как оживить элементы RecyclerView при инициализации адаптера (в порядке)?
Что я пытаюсь выполнить
Я хочу, чтобы элементы в линейном вертикальном RecyclerView отображались в порядке. Я хочу, чтобы появился первый пункт, затем второй, затем третий и так далее. Вот пример типа анимации, которую я пытаюсь выполнить.
![пример анимации]()
Что я пробовал
Я пробовал методы, предоставленные в этом вопросе: Как оживить элементы RecyclerView, когда они появляются
Однако это не совсем то, что я пытаюсь выполнить. Это приводит к тому, что все элементы в RecyclerView появляются сразу, а не по одному.
Мой код
public class ParentCommentsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private int lastPosition = -1;
//constructor and other code not shown...
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
switch (viewHolder.getItemViewType()) {
case OP:
OPViewHolder ovh = (OPViewHolder) viewHolder;
configureOPViewHolder(ovh, position);
setAnimation(ovh.getContainer(), position);
break;
case COMMENT:
CommentViewHolder cvh = (CommentViewHolder) viewHolder;
configureCommentViewHolder(cvh, position);
setAnimation(cvh.getContainer(), position);
break;
default:
RecyclerViewSimpleTextViewHolder vh = (RecyclerViewSimpleTextViewHolder) viewHolder;
configureDefaultViewHolder(vh, position);
break;
}
}
@Override
public void onViewDetachedFromWindow(final RecyclerView.ViewHolder viewHolder)
{
switch (viewHolder.getItemViewType()) {
case OP:
((OPViewHolder)viewHolder).clearAnimation();
break;
case COMMENT:
((CommentViewHolder)viewHolder).clearAnimation();
break;
default:
break;
}
}
private void configureDefaultViewHolder(RecyclerViewSimpleTextViewHolder vh, int position) {
//code...
}
private void configureOPViewHolder(OPViewHolder vh1, int position) {
//code...
}
private void configureCommentViewHolder(CommentViewHolder vh2, int position) {
//code...
}
private void setAnimation(View viewToAnimate, int position)
{
// If the bound view wasn't previously displayed on screen, it animated
if (position > lastPosition)
{
Animation animation = AnimationUtils.loadAnimation(context, R.anim.fade_in);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
}
Ответы
Ответ 1
После вызова setAdapter
вы можете выполнить следующее:
recyclerView.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
recyclerView.getViewTreeObserver().removeOnPreDrawListener(this);
for (int i = 0; i < recyclerView.getChildCount(); i++) {
View v = recyclerView.getChildAt(i);
v.setAlpha(0.0f);
v.animate().alpha(1.0f)
.setDuration(300)
.setStartDelay(i * 50)
.start();
}
return true;
}
});
Пример показывает простую альфа-анимацию, но вы можете запустить то, что хотите в цикле, и отрегулировать интерполятор, продолжительность и задержку запуска.
Ответ 2
Я решил использовать подход, отличный от того, что предложил Нико ранее. Его метод отлично работает и очень прост, но он вызывал некоторые глючные анимации при добавлении и удалении элементов (как можно увидеть здесь).
Поэтому я решил попробовать другой подход и использовать контроллер анимации макета. Вот код, который я использовал для достижения того же результата.
public void initialRVAnimation() {
AnimationSet set = new AnimationSet(true);
// Fade in animation
Animation fadeIn = new AlphaAnimation(0.0f, 1.0f);
fadeIn.setDuration(400);
fadeIn.setFillAfter(true);
set.addAnimation(fadeIn);
// Slide up animation from bottom of screen
Animation slideUp = new TranslateAnimation(0, 0, Utils.getScreenHeight(this), 0);
slideUp.setInterpolator(new DecelerateInterpolator(4.f));
slideUp.setDuration(400);
set.addAnimation(slideUp);
// Set up the animation controller (second parameter is the delay)
LayoutAnimationController controller = new LayoutAnimationController(set, 0.2f);
rv.setLayoutAnimation(controller);
// Set the adapter
adapter = new ItemAdapter(data, this);
recyclerView.setAdapter(adapter);
}
Ответ 3
Простой способ установить в XML в вашем теге RecyclerView (или в коде, как выше комментарий)
android:layoutAnimation="@anim/slide_left_in_layout_anim"
slide_left_in_layout_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation
xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@android:anim/slide_in_left"
android:delay="10%"
android:animationOrder="normal"
/>
Примечание: эта анимация оправдывается только при первой загрузке данных, если вы хотите добавить анимацию при добавлении/удалении/перемещении элемента, взгляните на ItemAnimator, и я думаю, что этот пост поможет вам узнать что-то полезное
Ответ 4
В дополнение к @Niko ответу для Kotlin попробуйте это решение.
позвоните после установки адаптера
rvTop!!.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
rvTop!!.getViewTreeObserver().removeOnPreDrawListener(this);
for (i in 0 until rvTop!!.getChildCount()) {
var v = rvTop!!.getChildAt(i);
v.setAlpha(0.0f);
v.animate().alpha(1.0f)
.setDuration(300)
.setStartDelay((i * 50).toLong())
.start();
}
return true
}
})