Android 如何在RecyclerView项出现时设置其动画
当出现时,如何设置RecyclerView项目的动画 默认项“动画制作”仅在设置回收器数据后添加或删除数据时才进行动画制作。我是新开发的应用程序,不知道从哪里开始Android 如何在RecyclerView项出现时设置其动画,android,android-layout,android-recyclerview,Android,Android Layout,Android Recyclerview,当出现时,如何设置RecyclerView项目的动画 默认项“动画制作”仅在设置回收器数据后添加或删除数据时才进行动画制作。我是新开发的应用程序,不知道从哪里开始 有什么办法可以做到这一点吗?编辑: 根据: 此类定义对适配器进行更改时在项目上发生的动画 因此,除非您将项目逐个添加到RecyclerView中,并在每次迭代时刷新视图,否则我认为ItemAnimator不是您需要的解决方案 以下是如何使用CustomAdapter设置RecyclerView项出现时的动画: public class
有什么办法可以做到这一点吗?编辑: 根据: 此类定义对适配器进行更改时在项目上发生的动画 因此,除非您将项目逐个添加到
RecyclerView
中,并在每次迭代时刷新视图,否则我认为ItemAnimator
不是您需要的解决方案
以下是如何使用CustomAdapter设置RecyclerView
项出现时的动画:
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;
}
}
}
在CustomViewHolder上:
public void clearAnimation()
{
mRootLayout.clearAnimation();
}
旧答案:
看看吧,我相信你会找到你需要的。他为RecyclerView提供了简单的项目动画师,如SlideInItemAnimator或SlideScaleItemAnimator。一个好的起点是: 您甚至不需要完整的库,这个类就足够了。 然后,如果您只是实现了适配器类,并提供如下动画:
@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);
}
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/layout_animation_fall_down"
/>
您将看到项目在滚动时从底部显示,这也避免了快速滚动的问题。当项目绑定到适配器中时,在recyclerview中设置项目动画可能不是最好的主意,因为这可能会导致recyclerview中的项目以不同的速度设置动画。在我的例子中,recyclerview末尾的项目比顶部的项目更快地移动到它们的位置,因为顶部的项目需要进一步移动,所以它看起来不整洁 我用来将每个项目动画化到recyclerview的原始代码可以在这里找到: 但我会复制并粘贴代码,以防链接中断 步骤1:在onCreate方法中设置此选项,以确保动画只运行一次:
if (savedInstanceState == null) {
pendingIntroAnimation = true;
}
步骤2:您需要将此代码放入要启动动画的方法中:
if (pendingIntroAnimation) {
pendingIntroAnimation = false;
startIntroAnimation();
}
在链接中,作者正在设置工具栏图标的动画,因此他将其放入此方法中:
@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()编写逻辑:
我的首选方案:
我宁愿为整个recyclerview设置动画,而不是为recyclerview中的项目设置动画
步骤1和2保持不变
在步骤3中,只要API调用返回数据,我就会启动动画
private void startIntroAnimation() {
recyclerview.setTranslationY(latestPostRecyclerview.getHeight());
recyclerview.setAlpha(0f);
recyclerview.animate()
.translationY(0)
.setDuration(400)
.alpha(1f)
.setInterpolator(new AccelerateDecelerateInterpolator())
.start();
}
这将设置整个recyclerview的动画,使其从屏幕底部飞入。我设置了
recyclerview
项目首次出现时的动画淡入,如下面的代码所示。也许这对某人有用
private final static int FADE_DURATION = 1000; //FADE_DURATION 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);
}
您还可以将setFadeAnimation()
替换为以下setScaleAnimation()
以通过从一点缩放项目来设置项目外观动画:
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
项目时,项目总是会褪色或缩放。如果您希望,可以添加代码,以便在首次创建包含RecyclerView
的片段或活动时仅允许动画发生(例如,获取创建时的系统时间,仅允许第一个淡入淡出持续时间毫秒).我从中创建了动画,只做了一点修改
,使动画只运行一次
换言之,动画仅在向下滚动时出现
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);
}
只需扩展适配器,如下所示
public class RankingAdapter extends AnimatedRecyclerView<RankingAdapter.ViewHolder>
这是一种自动创建动画适配器的方法,如“Basheer AL-MOMANI”
导入android.support.v7.widget.RecyclerView;
导入android.view.view;
导入android.view.ViewGroup;
导入android.view.animation.animation;
导入android.view.animation.ScaleAnimation;
导入java.util.Random;
/**
*由eliaszkubala于2017年2月24日创建。
*/
公共类animatedRecyclView扩展了RecyclView.Adapter{
@凌驾
public T onCreateViewHolder(视图组父级,int-viewType){
返回null;
}
@凌驾
公共无效onBindViewHolder(T holder,内部位置){
设置动画(holder.itemView,位置);
}
@凌驾
public int getItemCount(){
返回0;
}
受保护的int mLastPosition=-1;
受保护的void setAnimation(视图视图到动画,int位置){
如果(位置>mLastPosition){
缩放动画动画=新缩放动画(0.0f,1.0f,0.0f,1.0f,Animation.RELATIVE\u TO\u SELF,0.5f,Animation.RELATIVE\u TO\u SELF,0.5f);
anim.setDuration(new Random().nextInt(501));//使duration随机数介于[0501]之间
视图动画。开始动画(动画);
mLastPosition=位置;
}
}
}
将此方法创建到您的recyclerview适配器中
private void setZoomInAnimation(View view) {
Animation zoomIn = AnimationUtils.loadAnimation(context, R.anim.zoomin);// animation file
view.startAnimation(zoomIn);
}
最后在onBindViewHolder中添加这行代码
setZoominamination(holder.itemView);
您可以向RecyclerView
添加android:LayoutImation=“@anim/rv\u item\u 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);
}
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/layout_animation_fall_down"
/>
仅用XML简化
res/anim/layout\u animation.xml
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/item_animation_fall_down"
android:animationOrder="normal"
android:delay="15%" />
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500">
<translate
android:fromYDelta="-20%"
android:toYDelta="0"
android:interpolator="@android:anim/decelerate_interpolator"
/>
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:interpolator="@android:anim/decelerate_interpolator"
/>
<scale
android:fromXScale="105%"
android:fromYScale="105%"
android:toXScale="100%"
android:toYScale="100%"
android:pivotX="50%"
android:pivotY="50%"
android:interpolator="@android:anim/decelerate_interpolator"
/>
</set>
res/anim/item\u animation\u fall\u down.xml
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/item_animation_fall_down"
android:animationOrder="normal"
android:delay="15%" />
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500">
<translate
android:fromYDelta="-20%"
android:toYDelta="0"
android:interpolator="@android:anim/decelerate_interpolator"
/>
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:interpolator="@android:anim/decelerate_interpolator"
/>
<scale
android:fromXScale="105%"
android:fromYScale="105%"
android:toXScale="100%"
android:toYScale="100%"
android:pivotX="50%"
android:pivotY="50%"
android:interpolator="@android:anim/decelerate_interpolator"
/>
</set>
在布局和recylcerview中使用,如:
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layoutAnimation="@anim/layout_animation"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
2019年,
我建议将所有项目动画放入ItemAnimator
让我们从在“回收器”视图中声明动画师开始:
with(view.recycler_view) {
adapter = Adapter()
itemAnimator = CustomAnimator()
}
然后声明自定义动画师
class CustomAnimator() : DefaultItemAnimator() {
override fun animateAppearance(
holder: RecyclerView.ViewHolder,
preInfo: ItemHolderInfo?,
postInfo: ItemHolderInfo): Boolean{} // declare what happens when a item appears on the recycler view
override fun animatePersistence(
holder: RecyclerView.ViewHolder,
preInfo: ItemHolderInfo,
postInfo: ItemHolderInfo): Boolean {} // declare animation for items that persist in a recycler view even when the items change
}
与上面的类似,还有一个用于消失animateDisappearance
、添加animatedad
、更改animateChange
和移动animateMove
一个重要的问题是调用corr
class CustomAnimator() : DefaultItemAnimator() {
override fun animateAppearance(
holder: RecyclerView.ViewHolder,
preInfo: ItemHolderInfo?,
postInfo: ItemHolderInfo): Boolean{} // declare what happens when a item appears on the recycler view
override fun animatePersistence(
holder: RecyclerView.ViewHolder,
preInfo: ItemHolderInfo,
postInfo: ItemHolderInfo): Boolean {} // declare animation for items that persist in a recycler view even when the items change
}
override fun onViewAttachedToWindow(holder: ViewHolder) {
super.onViewAttachedToWindow(holder)
setBindAnimation(holder)
}