欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一个简单的自定义RecyclerView适配器(五)——动画

程序员文章站 2022-05-04 19:54:18
...

一、开启动画

在BaseRecyclerViewAdapter中

/**
 * 渐显动画,使用 {@link #openLoadAnimation}
 */
public static final int ALPHAIN = 0x00000001;
/**
 * 缩放动画,使用 {@link #openLoadAnimation}
 */
public static final int SCALEIN = 0x00000002;
/**
 * 从下到上动画,使用 {@link #openLoadAnimation}
 */
public static final int SLIDEIN_BOTTOM = 0x00000003;
/**
 * 从左到右动画,使用 {@link #openLoadAnimation}
 */
public static final int SLIDEIN_LEFT = 0x00000004;
/**
 * 从右到左动画,使用 {@link #openLoadAnimation}
 */
public static final int SLIDEIN_RIGHT = 0x00000005;

/**
 * 五种默认动画类型
 */
@IntDef({ALPHAIN, SCALEIN, SLIDEIN_BOTTOM, SLIDEIN_LEFT, SLIDEIN_RIGHT})
@Retention(RetentionPolicy.SOURCE)
private  @interface AnimationType {
}

/**
 * 是否开启动画标志,默认不打开
 */
private boolean mOpenAnimationEnable = false;

/**
 * 设置是否开启动画
 * @param mOpenAnimationEnable true为开启
 */
public void isOpenAnimationEnable(boolean mOpenAnimationEnable){
    this.mOpenAnimationEnable = mOpenAnimationEnable;
}

/**
 * 自定义动画基类
 */
private BaseAnimation mCustomAnimation;
public interface BaseAnimation {
    Animator[] getAnimators(View view);
}

/**
 * 自定义的默认动画
 */
private BaseAnimation mSelectAnimation;

/**
 * 使用默认的五种动画
 * 1.开启动画,2.使用自定义的默认动画,3.根据animationType选中动画类型
 * @param animationType ALPHAIN, SCALEIN, SLIDEIN_BOTTOM, SLIDEIN_LEFT, 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;
    }
}

/**
 * 使用自定义动画
 *
 * @param animation 自定义动画
 */
public void openLoadAnimation(BaseAnimation animation) {
    this.mOpenAnimationEnable = true;
    this.mCustomAnimation = animation;
}

使用

默认提供5种方法(渐显、缩放、从下到上,从左到右、从右到左)

mAdapter.openLoadAnimation(BaseRecyclerViewAdapter.ALPHAIN)

也可以自己自定义动画

mAdapter.openLoadAnimation(BaseRecyclerViewAdapter.BaseAnimation {
    arrayOf(ObjectAnimator.ofFloat(it, "scaleY", 1.0f, 1.1f, 1.0f), ObjectAnimator.ofFloat(it, "scaleX", 1.0f, 1.1f, 1.0f))
})

二、显示动画

在BaseRecyclerViewAdapter中

/**
 * 当列表项出现到可视界面的时候调用
 * @param holder holder
 */
@Override
public void onViewAttachedToWindow(@NonNull K holder) {
    super.onViewAttachedToWindow(holder);
    //显示动画
    addAnimation(holder);
}

/**
 * true只在加载数据时显示动画,false每次都显示动画
 */
private boolean mFirstOnlyEnable = true;
public void isFirstOnly(boolean firstOnly) {
    this.mFirstOnlyEnable = firstOnly;
}

/**
 * 统计有多少个动画
 */
private int mLastPosition = -1;

/**
 * 显示动画,默认只在加载数据时显示动画
 *
 * @param holder
 */
private void addAnimation(RecyclerView.ViewHolder holder) {
    if (mOpenAnimationEnable) {
        if (!mFirstOnlyEnable || holder.getLayoutPosition() > mLastPosition) {
            BaseAnimation animation;
            if (mCustomAnimation != null) {
                animation = mCustomAnimation;
            } else {
                animation = mSelectAnimation;
            }
            for (Animator anim : animation.getAnimators(holder.itemView)) {
                startAnim(anim, holder.getLayoutPosition());
            }
            mLastPosition = holder.getLayoutPosition();
        }
    }
}

/**
 * 动画时间
 */
private int mDuration = 1000;
public void setDuration(int duration) {
    mDuration = duration;
}

/**
 * 插值器,默认速率恒定
 */
private Interpolator mInterpolator = new LinearInterpolator();
public void setInterpolator(Interpolator mInterpolator){
    this.mInterpolator = mInterpolator;
}

/**
 * 设置动画时间,设置插值器,开启动画
 *
 * @param anim
 * @param position
 */
private void startAnim(Animator anim, int position) {
    anim.setDuration(mDuration).start();
    anim.setInterpolator(mInterpolator);
}

使用

//加载数据时是否显示动画,false为总是显示,默认为true
mAdapter.isFirstOnly(false)

//设置动画时间
mAdapter.setDuration(1000)
//设置插值器
mAdapter.setInterpolator(BounceInterpolator())

三、五种默认动画

public class AlphaInAnimation implements BaseRecyclerViewAdapter.BaseAnimation {
    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) {
        return new Animator[]{ObjectAnimator.ofFloat(view, "alpha", mFrom, 1f)};
    }
}

缩放动画

public class ScaleInAnimation implements BaseRecyclerViewAdapter.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) {
        ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", mFrom, 1f);
        ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", mFrom, 1f);
        return new ObjectAnimator[]{scaleX, scaleY};
    }
}

从下到上动画

public class SlideInBottomAnimation implements BaseRecyclerViewAdapter.BaseAnimation {
    @Override
    public Animator[] getAnimators(View view) {
        return new Animator[]{
                ObjectAnimator.ofFloat(view, "translationY", view.getMeasuredHeight(), 0)
        };
    }
}

从左到右动画

public class SlideInLeftAnimation implements BaseRecyclerViewAdapter.BaseAnimation {
    @Override
    public Animator[] getAnimators(View view) {
        return new Animator[]{
                ObjectAnimator.ofFloat(view, "translationX", -view.getRootView().getWidth(), 0)
        };
    }
}

从右到左动画

public class SlideInRightAnimation implements BaseRecyclerViewAdapter.BaseAnimation {
    @Override
    public Animator[] getAnimators(View view) {
        return new Animator[]{
                ObjectAnimator.ofFloat(view, "translationX", view.getRootView().getWidth(), 0)
        };
    }
}