如何在RecyclerView项目出现时进行animation制作

如何在RecyclerView出现时animation?

在设置回收站数据后,添加或删除数据时,默认项目animation设置器只会animation。 我是新开发的应用程序,并没有任何线索从哪里开始。

任何想法如何实现这一目标?

编辑:

根据ItemAnimator文档

该类定义了在对适配器进行更改时发生在项目上的animation。

所以除非你ItemAnimator添加你的项目到你的RecyclerView并在每次迭代刷新视图,我不认为ItemAnimator是你的需要的解决scheme。

以下是如何使用CustomAdapter显示RecyclerView项目时的animation效果:

 public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { private Context context; // The items to display in your RecyclerView private ArrayList<String> items; // Allows to remember the last item shown on screen private int lastPosition = -1; public static class ViewHolder extends RecyclerView.ViewHolder { TextView text; // You need to retrieve the container (ie the root ViewGroup from your custom_item_layout) // It's the view that will be animated FrameLayout container; public ViewHolder(View itemView) { super(itemView); container = (FrameLayout) itemView.findViewById(R.id.item_layout_container); text = (TextView) itemView.findViewById(R.id.item_layout_text); } } public CustomAdapter(ArrayList<String> items, Context context) { this.items = items; this.context = context; } @Override public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_item_layout, parent, false); return new ViewHolder(v); } @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.itemView, 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.slide_in_left); viewToAnimate.startAnimation(animation); lastPosition = position; } } } 

你的custom_item_layout看起来像这样:

 <FrameLayout android:id="@+id/item_layout_container" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/item_layout_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:minHeight="?android:attr/listPreferredItemHeightSmall"/> </FrameLayout> 

有关CustomAdapters和RecyclerView更多信息,请参阅官方文档中的这个培训

快速滚动的问题

使用这种方法可能会导致快速滚动的问题。 视图可以在animation发生时重用。 为了避免分离时build议清除animation。

  @Override public void onViewDetachedFromWindow(final RecyclerView.ViewHolder holder) { ((CustomViewHolder)holder).clearAnimation(); } 

在CustomViewHolder上:

  public void clearAnimation() { mRootLayout.clearAnimation(); } 

老答案:

看看Gabriele Mariotti的回购 ,我很肯定你会find你需要的。 他为RecyclerView提供了简单的ItemAnimators,比如SlideInItemAnimator或SlideScaleItemAnimator。

当它们第一次出现在下面的代码中时,我使Recyclerview项目淡入淡出。 也许这对某个人是有用的。

 private final static int FADE_DURATION = 1000 // in milliseconds @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.getTextView().setText("some text"); // Set the view to fade in setFadeAnimation(holder.itemView); } private void setFadeAnimation(View view) { AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f); anim.setDuration(FADE_DURATION); view.startAnimation(anim); } 

你也可以用下面的setScaleAnimation()来replacesetFadeAnimation() ,通过从一个点对它们进行缩放来animation项目的外观:

 private void setScaleAnimation(View view) { ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(FADE_DURATION); view.startAnimation(anim); } 

上面的代码有一些疣,当你滚动RecyclerView项目总是淡出或缩放。 如果你希望你可以添加代码来允许在首次创build包含RecyclerView的片段或活动时(例如,在创build时获取系统时间,并且只允许在第一个FADE_DURATION毫秒内animation),animation就会发生。

我从pbm的答案中创build了一些animation, 只做了一次modification

换句话说, Animation appear with you scroll down only

 private int lastPosition = -1; private void setAnimation(View viewToAnimate, int position) { // If the bound view wasn't previously displayed on screen, it's animated if (position > lastPosition) { ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(new Random().nextInt(501));//to make duration random number between [0,501) viewToAnimate.startAnimation(anim); lastPosition = position; } } 

并在onBindViewHolder调用该函数

 @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.getTextView().setText("some text"); // call Animation function setAnimation(holder.itemView, position); } 

一个好的开始是这样的: https : //github.com/wasabeef/recyclerview-animators/blob/master/animators/src/main/java/jp/wasabeef/recyclerview/adapters/AnimationAdapter.java

你甚至不需要完整的图书馆,那个class就够了。 那么如果你只是实现你的Adapter类给一个animation师这样的:

 @Override protected Animator[] getAnimators(View view) { return new Animator[]{ ObjectAnimator.ofFloat(view, "translationY", view.getMeasuredHeight(), 0) }; } @Override public long getItemId(final int position) { return getWrappedAdapter().getItemId(position); } 

您将在滚动时看到从底部出现的项目,也避免了快速滚动的问题。

在回收站视图中绑定到适配器中时,将其中的项目设置为animation可能不是最好的主意,因为这可能会导致回收站视图中的项目以不同的速度animation。 在我的情况下,回收者查看结束时的项目更快地animation到他们的位置,然后顶部的项目进一步旅行,所以它看起来不整洁。

我用来将每个项目animation到recyclerview的原始代码可以在这里find:

http://frogermcs.github.io/Instagram-with-Material-Design-concept-is-getting-real/

但是我会复制并粘贴代码,以防链接中断。

第一步:在你的onCreate方法里面设置这个,这样可以确保animation只运行一次:

 if (savedInstanceState == null) { pendingIntroAnimation = true; } 

第2步:您需要将此代码放入要启动animation的方法中:

 if (pendingIntroAnimation) { pendingIntroAnimation = false; startIntroAnimation(); } 

在这个链接中,作者是animation工具栏的图标,所以他把它放在这个方法里面:

 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); inboxMenuItem = menu.findItem(R.id.action_inbox); inboxMenuItem.setActionView(R.layout.menu_item_view); if (pendingIntroAnimation) { pendingIntroAnimation = false; startIntroAnimation(); } return true; } 

第3现在编写startIntroAnimation()的逻辑:

 private static final int ANIM_DURATION_TOOLBAR = 300; private void startIntroAnimation() { btnCreate.setTranslationY(2 * getResources().getDimensionPixelOffset(R.dimen.btn_fab_size)); int actionbarSize = Utils.dpToPx(56); toolbar.setTranslationY(-actionbarSize); ivLogo.setTranslationY(-actionbarSize); inboxMenuItem.getActionView().setTranslationY(-actionbarSize); toolbar.animate() .translationY(0) .setDuration(ANIM_DURATION_TOOLBAR) .setStartDelay(300); ivLogo.animate() .translationY(0) .setDuration(ANIM_DURATION_TOOLBAR) .setStartDelay(400); inboxMenuItem.getActionView().animate() .translationY(0) .setDuration(ANIM_DURATION_TOOLBAR) .setStartDelay(500) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { startContentAnimation(); } }) .start(); } 

我更喜欢的select:

我宁愿animation整个recyclerview而不是recyclerview内的项目。

步骤1和2保持不变。

在STEP 3中,只要您的API调用返回数据,我就开始animation。

 private void startIntroAnimation() { recyclerview.setTranslationY(latestPostRecyclerview.getHeight()); recyclerview.setAlpha(0f); recyclerview.animate() .translationY(0) .setDuration(400) .alpha(1f) .setInterpolator(new AccelerateDecelerateInterpolator()) .start(); } 

这将animation您的整个recyclerview,以便它从屏幕的底部飞入。

只需像下面一样扩展适配器

 public class RankingAdapter extends AnimatedRecyclerView<RankingAdapter.ViewHolder> 

并添加超级方法onBindViewHolder

 @Override public void onBindViewHolder(ViewHolder holder, final int position) { super.onBindViewHolder(holder, position); 

这是自动化的方式来创build像“Basheer AL-MOMANI”

 import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.ScaleAnimation; import java.util.Random; /** * Created by eliaszkubala on 24.02.2017. */ public class AnimatedRecyclerView<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<T> { @Override public T onCreateViewHolder(ViewGroup parent, int viewType) { return null; } @Override public void onBindViewHolder(T holder, int position) { setAnimation(holder.itemView, position); } @Override public int getItemCount() { return 0; } protected int mLastPosition = -1; protected void setAnimation(View viewToAnimate, int position) { if (position > mLastPosition) { ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); anim.setDuration(new Random().nextInt(501));//to make duration random number between [0,501) viewToAnimate.startAnimation(anim); mLastPosition = position; } } } 

创build这个方法到你的recyclerview适配器

 private void setZoomInAnimation(View view) { Animation zoomIn = AnimationUtils.loadAnimation(context, R.anim.zoomin);// animation file view.startAnimation(zoomIn); } 

最后在onBindViewHolder中添加这一行代码

setZoomInAnimation(holder.itemView);

将此行添加到RecyclerView.xml

 android:animateLayoutChanges="true"