📜  如何在Android的RecyclerView中添加淡入淡出和收缩动画?(1)

📅  最后修改于: 2023-12-03 14:52:39.874000             🧑  作者: Mango

如何在Android的RecyclerView中添加淡入淡出和收缩动画

RecyclerView 是 Android 中应用广泛的列表控件,通过 RecyclerView 可以长驻内存中保持列表数据,同时可以灵活地对列表项进行定制。在 RecyclerView 中添加淡入淡出和收缩动画可以提升用户体验,增强应用的交互效果。在以下的阐述中我们将学习如何在 Android 的 RecyclerView 中添加淡入淡出动画和收缩动画。

淡入淡出动画
实现淡入淡出动画

在 RecyclerView 中添加淡入淡出的动画可以使得列表项在出现和消失时更平滑的实现。 RecyclerView 自身并没有提供淡入淡出动画的实现,需要使用 ItemAnimator 来实现。ItemAnimator 的主要功能是控制 RecyclerView 中子view的添加、移除、刷新动画效果。在默认情况下,ItemAnimator 是空实现,即并没有任何动画效果。我们来看如何使用 ItemAnimator 来实现淡入淡出动画。

public class FadeInAnimator extends DefaultItemAnimator {
    
    @Override
    public boolean animateAdd(RecyclerView.ViewHolder holder) {
        holder.itemView.setAlpha(0f);
        ViewCompat.animate(holder.itemView)
            .alpha(1f)
            .setDuration(getAddDuration())
            .setListener(new ViewPropertyAnimatorListener() {
                @Override
                public void onAnimationStart(View view) {
                }
                
                @Override
                public void onAnimationEnd(View view) {
                }
                
                @Override
                public void onAnimationCancel(View view) {
                }
            })
            .start();
        return true;
    }
    
    @Override
    public boolean animateRemove(RecyclerView.ViewHolder holder) {
        ViewCompat.animate(holder.itemView)
            .alpha(0f)
            .setDuration(getRemoveDuration())
            .setListener(new ViewPropertyAnimatorListener() {
                @Override
                public void onAnimationStart(View view) {
                }
                
                @Override
                public void onAnimationEnd(View view) {
                    dispatchRemoveFinished(holder);
                }
                
                @Override
                public void onAnimationCancel(View view) {
                
                }
            })
            .start();
        return true;
    }
    
}

在上述代码中,我们继承了 DefaultItemAnimator 类,并实现了 animateAdd 和 animateRemove 方法,这两个方法是 ItemAnimator 中的核心方法,分别控制子view的添加和移除动画。在 animateAdd 方法中,我们在子view 的初始透明度上设置为 0,然后通过 ViewCompat.animate 方法来实现透明度的淡入动画,动画时长通过 getAddDuration 方法获取。在 animateRemove 方法中,我们同样使用 ViewCompat.animate 方法来实现透明度的淡出动画,动画时长通过 getRemoveDuration 方法获取。

为 RecyclerView 添加淡入淡出动画

我们已经实现了淡入淡出动画,接下来我们将这个动画添加到 RecyclerView 中。

FadeInAnimator fadeInAnimator = new FadeInAnimator();
recyclerView.setItemAnimator(fadeInAnimator);

通过 setItemAnimator 方法来将自定义的动画 fadeInAnimator 添加到 RecyclerView 中即可。 完整的代码如下所示:

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(new MyRecyclerViewAdapter());
        
        FadeInAnimator fadeInAnimator = new FadeInAnimator();
        recyclerView.setItemAnimator(fadeInAnimator);
    }
}
收缩动画
实现收缩动画

RecyclerView 中的收缩动画通常用于在点击列表项时将其背景色从高亮变成默认,或者将 列表项恢复到正常状态。实现收缩动画同样需要使用 ItemAnimator 类。以下代码演示如何实现一个简单的收缩动画。

public class ShrinkAnimator extends DefaultItemAnimator {
    @Override
    public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, 
        int fromX, int fromY, int toX, int toY) {
        return super.animateChange(oldHolder, newHolder, fromX, fromY, toX, toY);
    }
    @Override
    public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
        return super.animateMove(holder, fromX, fromY, toX, toY);
    }
    @Override
    public boolean animateAdd(RecyclerView.ViewHolder holder) {
        return super.animateAdd(holder);
    }
    @Override
    public boolean animateRemove(final RecyclerView.ViewHolder holder) {
        ValueAnimator animator = ValueAnimator.ofInt(holder.itemView.getHeight(), 0).setDuration(getRemoveDuration());
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                dispatchRemoveFinished(holder);
            }
        });
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int value = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
                layoutParams.height = value;
                holder.itemView.setLayoutParams(layoutParams);
            }
        });
        animator.start();
        return true;
    }
}

我们继承了 DefaultItemAnimator 类,并重写了 animateRemove 方法。 在 animateRemove 方法中,我们首先创建一个 ValueAnimator 对象,并设置初始值为 holder.itemView.getHeight(),最终值为 0,时长为 getRemoveDuration()。然后添加动画结束监听器, 在其 onAnimationEnd 方法中调用 dispatchRemoveFinished() 方法完成对 RecyclerView 中对该 Item 的移除操作。 接下来我们添加动画更新监听器,通过改变布局的高度来实现类似于收缩的动画效果。

为 RecyclerView 添加收缩动画

将收缩动画添加到 RecyclerView 中同样只需要在初始化 RecyclerView 的代码中添加以下片段即可。

ShrinkAnimator shrinkAnimator = new ShrinkAnimator();
recyclerView.setItemAnimator(shrinkAnimator);

完整的代码如下所示:

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(new MyRecyclerViewAdapter());
        
        FadeInAnimator fadeInAnimator = new FadeInAnimator();
        ShrinkAnimator shrinkAnimator = new ShrinkAnimator();
        recyclerView.setItemAnimator(fadeInAnimator);
        recyclerView.setItemAnimator(shrinkAnimator);
    }
}

至此,我们已经学习了如何在 Android 的 RecyclerView 中添加淡入淡出和收缩动画,希望本文可以对大家有所帮助。