如何在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"