CardView в RecyclerView: анимация при заполнении

У меня есть переработанное представление, которое заполнено макетами CardView. Я заметил, что во многих приложениях эти элементы имеют приятный анимированный вход, а не внезапно появляются, как они это делают в моем приложении. Пример того, что я пытаюсь достичь, показан ниже: Введите описание изображения здесь

Как я могу использовать свой swipeRefreshListener / adapter для запуска этой анимации? Как реализовать это через адаптер?

Примечание. Мне нужна эта анимация, которая также запускается, когда RecyclerView сначала заполняется элементами CardView и данными, которые они содержат.

Мой адаптер RecyclerView показан ниже:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> { private String[] mDataset; private String[] mClassDataset; private int lastPosition = -1; private Context context; View view; public static class ViewHolder extends RecyclerView.ViewHolder { public TextView mTextView; public TextView mClassDataView; CardView container; public ViewHolder(View itemView) { super(itemView); mTextView = (TextView)itemView.findViewById(R.id.grade); mClassDataView = (TextView)itemView.findViewById(R.id.class_name); container = (CardView)itemView.findViewById(R.id.card_view); } } public RecyclerAdapter(String[] myDataset, String[] classData, Context context) { mDataset = myDataset; mClassDataset = classData; this.context = context; } @Override public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.card_item, parent, false); ViewHolder vh = new ViewHolder(v); view = v; return vh; } @Override public int getItemCount() { return mClassDataset.length; } @Override public void onBindViewHolder(final ViewHolder holder, final int position) { if (mDataset.length < mClassDataset.length) { holder.mTextView.setText("N/A"); holder.mClassDataView.setText(mClassDataset[position]); if (mClassDataset[position].equals("N/A")) { } } else { holder.mTextView.setText(mDataset[position]); holder.mClassDataView.setText(mClassDataset[position]); } for (int i = 0; i < getItemCount(); i++) { animate(view, i); } } private void animate(final View view, final int position){ Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left); view.startAnimation(animation); lastPosition = position; } } 

Анимация в настоящее время работает, однако вещь состоит в том, что элементы анимируются все сразу. Я попытался выполнить итерацию элементов, создав собственный метод getChild() , но это не сработало. Как-то мне нужно получить доступ / оживить каждого ребенка по отдельности и, возможно, установить задержку между каждой анимацией. Однако я не уверен, как именно я могу это сделать. Я знаю, что я могу использовать Handler для установки задержки, но доступ к каждому ребенку является проблемой.

Используйте этот пользовательский класс RecyclerView , он ведет себя как приложение, которое вы разместили на снимке (Reddit Relay), оно предотвращает прокрутку во время анимации первых элементов. Вы можете настроить анимацию по своему усмотрению.

 package net.leolink.android.testrecyclerviewentranceanimation; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; /** * @author Leo on 2015/09/03 */ public class MyRecyclerView extends RecyclerView { private boolean mScrollable; public MyRecyclerView(Context context) { this(context, null); } public MyRecyclerView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyRecyclerView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mScrollable = false; } @Override public boolean dispatchTouchEvent(MotionEvent ev) { return !mScrollable || super.dispatchTouchEvent(ev); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); for (int i = 0; i < getChildCount(); i++) { animate(getChildAt(i), i); if (i == getChildCount() - 1) { getHandler().postDelayed(new Runnable() { @Override public void run() { mScrollable = true; } }, i * 100); } } } private void animate(View view, final int pos) { view.animate().cancel(); view.setTranslationY(100); view.setAlpha(0); view.animate().alpha(1.0f).translationY(0).setDuration(300).setStartDelay(pos * 100); } } 

DEMO

демонстрация

Для RecyclerView вы можете использовать ItemAnimators, установив их с помощью этого метода:

 RecyclerView.setItemAnimator(RecyclerView.ItemAnimator animator) 

Существует несколько библиотек, которые реализуют этот ItemAnimator, например, этот: https://github.com/wasabeef/recyclerview-animators

Сначала определите анимацию:

 <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="300"/> <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" /> </set> 

Затем установите его в адаптер:

  @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.text.setText(items.get(position)); // Here you apply the animation when the view is bound setAnimation(holder.container, position); } /** * Here is the key method to apply the animation */ private void setAnimation(View viewToAnimate, int position) { // If the bound view wasn't previously displayed on screen, it's animated if (position > lastPosition) { Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.push_left_in); viewToAnimate.startAnimation(animation); lastPosition = position; } } 

Ссылка на: RecyclerView: как создать эффект анимации вставки?