BaseRecyclerViewAdapterHelper源码解读(三) 添加动画
来源:互联网 发布:ife矩阵结果分析 编辑:程序博客网 时间:2024/06/04 21:58
一行代码轻松切换5种默认动画
此篇文章为BaseRecyclerViewAdapterHelper源码解读第三篇,开源库地址,如果没有看过之前2篇文章的同学可以先去看看,大神可直接跳过.
BaseRecyclerViewAdapterHelper源码解读(一) 封装简单的adapter和万能的BaseViewHolder
BaseRecyclerViewAdapterHelper源码解读(二) 添加header和footer
今天给大家带来BaseRecyclerViewAdapterHelper是如何添加动画的.由于本人才学尚浅,如有有不对的地方,欢迎指正,谢谢.
一,定义5种默认动画类型
这5种动画是默认的,外界可以直接使用者5种动画,当然也支持自定义.
BaseAnimation 动画的父类
public interface BaseAnimation { /** * 返回一个Animator数组,方便扩展,可以在view上加多个动画 * @param view * @return */ Animator[] getAnimators(View view);}
下面再看看实现类
AlphaInAnimation
/** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper * 渐显 */public class AlphaInAnimation implements BaseAnimation { /** * 默认透明度从0 */ private static final float DEFAULT_ALPHA_FROM = 0f; private final float mFrom; public AlphaInAnimation() { this(DEFAULT_ALPHA_FROM); } public AlphaInAnimation(float from) { mFrom = from; } @Override public Animator[] getAnimators(View view) { //返回一个Animator数组 将动画附加到view上,透明度从mFrom-1f return new Animator[]{ObjectAnimator.ofFloat(view, "alpha", mFrom, 1f)}; }}
其实就是设置一个属性动画在view上,然后将Animator数组返回,外界就可以直接调用
anim.setDuration(mDuration).start();设置动画时长并开启加载动画了.
ScaleInAnimation
/** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper * 缩放 */public class ScaleInAnimation implements BaseAnimation { private static final float DEFAULT_SCALE_FROM = .5f; private final float mFrom; public ScaleInAnimation() { this(DEFAULT_SCALE_FROM); } public ScaleInAnimation(float from) { mFrom = from; } @Override public Animator[] getAnimators(View view) { //设置scaleX和scaleY都从mFrom-1f ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", mFrom, 1f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", mFrom, 1f); return new ObjectAnimator[]{scaleX, scaleY}; }}
SlideInBottomAnimation
/** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper * 从下往上 */public class SlideInBottomAnimation implements BaseAnimation { @Override public Animator[] getAnimators(View view) { //这里设置的是view的纵坐标,从view.getMeasuredHeight()-0,相当于从下往上移动自身的高度 return new Animator[]{ ObjectAnimator.ofFloat(view, "translationY", view.getMeasuredHeight(), 0) }; }}
SlideInLeftAnimation
/** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper * 从左往右 */public class SlideInLeftAnimation implements BaseAnimation { @Override public Animator[] getAnimators(View view) { //view 的translationX 从 -顶层root view的宽度~0 return new Animator[]{ ObjectAnimator.ofFloat(view, "translationX", -view.getRootView().getWidth(), 0) }; }}
SlideInRightAnimation
/** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper * 从右往左 */public class SlideInRightAnimation implements BaseAnimation { @Override public Animator[] getAnimators(View view) { //view 的translationX 从 顶层root view的宽度~0 return new Animator[]{ ObjectAnimator.ofFloat(view, "translationX", view.getRootView().getWidth(), 0) }; }}
SlideInTopAnimation
从上往下,这是我自己加的,感觉这种动画效果很不错嘛
/** * author feiyang * create at 2017/10/19 10:37 * description:从上往下 */public class SlideInTopAnimation implements BaseAnimation { @Override public Animator[] getAnimators(View view) { return new Animator[]{ ObjectAnimator.ofFloat(view, "translationY", -view.getMeasuredHeight(), 0)}; }}
二,再看看BaseQuickAdapter
//Animation /** * Use with {@link #openLoadAnimation} */ public static final int ALPHAIN = 0x00000001; /** * Use with {@link #openLoadAnimation} */ public static final int SCALEIN = 0x00000002; /** * Use with {@link #openLoadAnimation} */ public static final int SLIDEIN_BOTTOM = 0x00000003; /** * Use with {@link #openLoadAnimation} */ public static final int SLIDEIN_LEFT = 0x00000004; /** * Use with {@link #openLoadAnimation} */ public static final int SLIDEIN_RIGHT = 0x00000005; @IntDef({ALPHAIN, SCALEIN, SLIDEIN_BOTTOM, SLIDEIN_LEFT, SLIDEIN_RIGHT}) @Retention(RetentionPolicy.SOURCE) public @interface AnimationType { } /** * 动画只执行1次? */ private boolean mFirstOnlyEnable = true; /** * 开启了动画? */ private boolean mOpenAnimationEnable = false; private Interpolator mInterpolator = new LinearInterpolator(); /** * 动画播放时长 */ private int mDuration = 300; /** * 上一个在播放动画的item的位置 */ private int mLastPosition = -1; /** * 自定义的动画 */ private BaseAnimation mCustomAnimation; /** * 当前选择使用哪种动画 */ private BaseAnimation mSelectAnimation = new AlphaInAnimation();
上面就是定义了5种默认的动画
- ALPHAIN 渐显
- SCALEIN 缩放
- SLIDEIN_BOTTOM 从下到上
- SLIDEIN_LEFT 从左到右
- SLIDEIN_RIGHT 从右到左
并且下面还定义了AnimationType,这里是注解类型有点类似于枚举,就是当使用@AnimationType修饰的参数时只能使用上面的5种动画常量中的1种.关于枚举,其实很有必要学习一下,在很多时候可以规范我们的编码,可以看看Airsaid大神写的Android 中注解的使用.
后面是一些其他的属性,已加入详细注释.
设置从哪个item开始执行动画
/** * up fetch end * 设置count个不执行动画 */ public void setNotDoAnimationCount(int count) { mLastPosition = count; }
可以看到,将mLastPosition设置为count,mLastPosition之前的item是不会被加载动画了.
当视图附加到窗口时,开始执行动画
/** * Called when a view created by this adapter has been attached to a window. * simple to solve item will layout using all * * {@link #setFullSpan(RecyclerView.ViewHolder)} * * @param holder */ @Override public void onViewAttachedToWindow(K holder) { super.onViewAttachedToWindow(holder); int type = holder.getItemViewType(); if (type == EMPTY_VIEW || type == HEADER_VIEW || type == FOOTER_VIEW || type == LOADING_VIEW) { //设置为跨区域 比如是StaggeredGridLayoutManager时,header或者footer等应该如何展示 setFullSpan(holder); } else { //添加动画到holder的itemView上,并执行动画 addAnimation(holder); } } /** * add animation when you want to show time * 添加动画到item上并执行动画 * @param holder */ private void addAnimation(RecyclerView.ViewHolder holder) { // 判断是否开启了动画 if (mOpenAnimationEnable) { // !isFirstOnly 这一次item的位置>上一次加载动画item的位置 if (!mFirstOnlyEnable || holder.getLayoutPosition() > mLastPosition) { BaseAnimation animation = null; //判断是否是自定义了动画 if (mCustomAnimation != null) { animation = mCustomAnimation; } else { //没有自定义,则使用默认的动画 animation = mSelectAnimation; } // 遍历定义到holder.itemView上的动画 BaseAnimation使用的getAnimators()是获取动画数组,方便扩展 // 如果用户需要自定义动画的话,则可以在一个item上同时加入多个动画,然后下面让这些动画依次执行 for (Animator anim : animation.getAnimators(holder.itemView)) { //开启动画 startAnim(anim, holder.getLayoutPosition()); } //记录这一次执行动画的item mLastPosition = holder.getLayoutPosition(); } } } /** * set anim to start when loading * 开启动画并设置插值器 * @param anim * @param index */ protected void startAnim(Animator anim, int index) { anim.setDuration(mDuration).start(); anim.setInterpolator(mInterpolator); }
- 当view被添加到window时,给view附加动画到上面去,然后开始执行动画.
- 在addAnimation()时首先是判断了是否开启动画,再判断是否是只需要显示一次,再根据是否是自定义的动画然后生成不同的animation,遍历Animator数组开始依次执行动画.
设置动画类型
/** * Set the view animation type. * 设置动画类型 * @param animationType One of {@link #ALPHAIN}, {@link #SCALEIN}, {@link #SLIDEIN_BOTTOM}, * {@link #SLIDEIN_LEFT}, {@link #SLIDEIN_RIGHT}. */ public void openLoadAnimation(@AnimationType int animationType) { //标志着需要加载动画 this.mOpenAnimationEnable = true; //用户没有自定义动画 是使用的默认动画 mCustomAnimation = null; //根据用户传入的类型初始化应该使用哪种动画 switch (animationType) { case ALPHAIN: mSelectAnimation = new AlphaInAnimation(); break; case SCALEIN: mSelectAnimation = new ScaleInAnimation(); break; case SLIDEIN_BOTTOM: mSelectAnimation = new SlideInBottomAnimation(); break; case SLIDEIN_LEFT: mSelectAnimation = new SlideInLeftAnimation(); break; case SLIDEIN_RIGHT: mSelectAnimation = new SlideInRightAnimation(); break; default: break; } } /** * Set Custom ObjectAnimator * 自定义动画 * @param animation ObjectAnimator */ public void openLoadAnimation(BaseAnimation animation) { //标志着需要加载动画 this.mOpenAnimationEnable = true; //初始化自定义动画 this.mCustomAnimation = animation; } /** * To open the animation when loading * 开启动画,这种情况下会默认开启:渐显动画 */ public void openLoadAnimation() { this.mOpenAnimationEnable = true; } /** * {@link #addAnimation(RecyclerView.ViewHolder)} * 设置动画是否只加载一次 * @param firstOnly true just show anim when first loading false show anim when load the data * every time true:第一次显示时才加载动画 false:每次都加载动画 */ public void isFirstOnly(boolean firstOnly) { this.mFirstOnlyEnable = firstOnly; }
这里主要是做一些配置信息的初始化
- 动画类型
- 自定义动画配置
- 是否只需要加载一次
总结
- 其实今天的重点是onViewAttachedToWindow(),当view被添加到window时,通过holder找到view,给view依次执行动画.
- 其他的都是一些修饰,比如在开源库中自带了几种默认的动画效果可以提供给开发者选择,显得更加人性化.
- 其次,该开源库这样设计之后不仅调用简单,只需一行代码.而且还支持自定义动画.
- 再其次,该开源库真的超级强大,大家有空多看看源码,收获颇多.
- 最后,感谢开发者的无私奉献,该开源库地址:https://github.com/CymChad/BaseRecyclerViewAdapterHelper
- BaseRecyclerViewAdapterHelper源码解读(三) 添加动画
- BaseRecyclerViewAdapterHelper源码解读(二) 添加header和footer
- BaseRecyclerViewAdapterHelper源码解读(六) 分组布局
- BaseRecyclerViewAdapterHelper源码解读(七) 多布局
- BaseRecyclerViewAdapterHelper源码解读(八) 空布局
- BaseRecyclerViewAdapterHelper源码解读(四) 上拉加载更多
- BaseRecyclerViewAdapterHelper源码解读(五) header和footer完善
- BaseRecyclerViewAdapterHelper源码解读(一) 封装简单的adapter和万能的BaseViewHolder
- THUCTC源码解读(三)
- hadoop源码解读三
- BaseRecyclerViewAdapterHelper开源项目之BaseQuickAdapter源码学习上拉加载的实现代码(三)
- SEDA源码解读(三)
- jieba分词源码解读三
- 比特币源码解读三
- BaseRecyclerViewAdapterHelper
- BaseRecyclerViewAdapterHelper
- Caffe源码解读(三):Layer类的源码解读
- jpcsp源码解读之三:Screen类
- Cocos Code IDE 1.2.0 下载地址
- python重复list中元素中的字母次数
- 近5年133个Java面试问题列表
- mybatis插入与取出 blob clob字段
- 【JDK集合框架源码分析】-集合框架概述
- BaseRecyclerViewAdapterHelper源码解读(三) 添加动画
- 在Spring Boot框架下使用WebSocket实现消息推送
- Hadoop生态系统之Hive和HBase and Zookeeper
- 详解匿名内部类
- JAVA Spring HelloWord实现
- java作业
- 2---要多尝试学习新的设计方式
- git eclipse push 报错—(change 164 closed)
- 世界上第一个时序数据的Middle-Out算法压缩