更流畅的滑动体验 给RecycleView的item显示加上动画
一.按照传统 先说我们想要的效果:
效果图一.gif 效果图二.gif这就是我们想要的效果 在recycleview的item显示在屏幕上的时候 添加一个简单的动画效果(由50%放大到100%)
二.实现步骤:
首先按正常的流程,使用Recyceview实现下拉刷新和上拉加载更多:
https://www.jianshu.com/p/0dd105736eaa
然后准备一个视图动画 我们想要的只有一个由50%放大到100%的效果 :
在res/anim新建一个xml文件scale_50_to_100
,内容为:
(第三行 增加了一个先慢后快的插值器 accelerate_interpolator
,也可也不加,这里只是记录以下插值器的使用)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
>
<!--缩放动画标签-->
<scale
android:fromXScale="0.5"
android:toXScale="1.0"
android:fromYScale="0.5"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"/>
</set>
关于视图动画的使用参考:https://blog.csdn.net/yanbober/article/details/46481171
接下来在Recycleview的adapter中使用动画
在Holder中为每个item填写好数据后,添加动画
@Override
public void setData(@NonNull NewsBean data, int position) {
newsTitle.setText(data.getTitle());
newsSource.setText(data.getSource());
newsTime.setText(data.getTime());
Glide.with(itemView.getContext()).load(data.getImageUrl())
.thumbnail(Glide.with(itemView.getContext()).load(R.drawable.loding))
.into(newsImg);
//添加itemView的动画 这里是直接为整个itemView添加一个动画
//也可以为itemView中的局部View 比如ImageView添加动画
Animation animation = AnimationUtils.loadAnimation(itemView.getContext(),R.anim.scale_50_to_100);
itemView.startAnimation(animation);
}
这样我们想要的效果就实现了
可能会遇到的一点点问题:
仔细观察"效果图二"也就是那个美女的效果图会发现一个问题,就是我们在上拉加载更多后,原本存在于页面上的图片item也重新播放了动画
原因分析:
因为在加载更多添加数据后,调用了adapter.notifyDataSetChanged()
导致所有item一起刷新了
@Override
public void showMoreData(List<PicEntity.ResultBean> data) {
mData.addAll(data);
mAdapter.notifyDataSetChanged();
}
解决方法:https://www.cnblogs.com/ganchuanpu/p/8000926.html
@Override
public void showMoreData(List<PicEntity.ResultBean> data) {
//记录当前的最底部的item位置
int position=mData.size()-1;
//增加数据
mData.addAll(data);
//只调用notifyItemRangeChanged方法 刷新之后新添加进来的数据的item
//这样就不会导致动画重复
mAdapter.notifyItemRangeChanged(position+1,data.size());
}
RecyclerView中notifyDataSetChanged刷新总结
除了adapter.notifyDataSetChanged()
这个方法之外,新的Adapter还提供了其他的方法,如下:
public final void notifyDataSetChanged()
public final void notifyItemChanged(int position)
public final void notifyItemRangeChanged(int positionStart, int itemCount)
public final void notifyItemInserted(int position)
public final void notifyItemMoved(int fromPosition, int toPosition)
public final void notifyItemRangeInserted(int positionStart, int itemCount)
public final void notifyItemRemoved(int position)
public final void notifyItemRangeRemoved(int positionStart, int itemCount)
基本上看到方法的名字就知道这个方法是干嘛的了,
第一个方法没什么好讲的,跟以前一样。
notifyItemChanged(int position)
,position数据发生了改变,那调用这个方法,就会回调对应position的onBindViewHolder()
方法了,当然,因为ViewHolder是复用的,所以如果position在当前屏幕以外,也就不会回调了,因为没有意义,下次position滚动会当前屏幕以内的时候同样会调用onBindViewHolder()
方法刷新数据了。其他的方法也是同样的道理。
public final void notifyItemRangeChanged(int positionStart, int itemCount)
,顾名思义,可以刷新从positionStart开始itemCount数量的item了(这里的刷新指回调onBindViewHolder()方法)。
public final void notifyItemInserted(int position)
,这个方法是在第position位置被插入了一条数据的时候可以使用这个方法刷新,注意这个方法调用后会有插入的动画,这个动画可以使用默认的,也可以自己定义。
public final void notifyItemMoved(int fromPosition, int toPosition)
,这个方法是从fromPosition移动到toPosition为止的时候可以使用这个方法刷新
public final void notifyItemRangeInserted(int positionStart, int itemCount)
,显然是批量添加。
public final void notifyItemRemoved(int position)
,第position个被删除的时候刷新,同样会有动画。
public final void notifyItemRangeRemoved(int positionStart, int itemCount)
,批量删除。