Android实现控件聚合动画效果

共 3426字,需浏览 7分钟

 ·

2021-09-30 20:18

效果展示


效果是当切换到页面2的时候执行聚合动画



实现步骤


1、继承LinearLayout

因为我实现的效果继承LinearLayout比较方便,这里也可以继承其他已有的ViewGroup

public class AnimationLinearLayout extends LinearLayout {    public AnimationLinearLayout(Context context) {        this(context, null);    }
public AnimationLinearLayout(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); }
public AnimationLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }}


2、实现动画


这里就是将所有的直接子控件通过循环全部执行TranslateAnimation动画,这里我使用动画方式的是相对于父容器来在Y轴方向平移的

/**     * 开始动画(补间动画)     */    public void startTweenAnim(@NonNull AnimType animType){        float startVal;        for (int i = 0; i < getChildCount(); i++) {            View childView = getChildAt(i);            startVal = 0.1f + i / 20f;            if(animType == AnimType.DOWN){                startVal = -(0.1f + (getChildCount() - 1 - i) / 20f);            }            TranslateAnimation animation=new TranslateAnimation(RELATIVE_TO_PARENT,0,RELATIVE_TO_PARENT,0,RELATIVE_TO_PARENT                    ,startVal ,RELATIVE_TO_PARENT,0);            animation.setDuration(700);//设置单次动画的重复时间            animation.setFillAfter(false);//设置动画结束后是否保持结束时的状态,默认为false            childView.startAnimation(animation);        }    }


这里定义了一个结构体,是用来设置聚合的方向的,例如文章开头展示的效果就是上半部分向下聚合,下半部分向下聚合实现的

/**     * 动画的类型     */    public enum AnimType{        UP,//向上        DOWN//向下    }


而我们向下聚合的话就是让控件从上往下平移,所以就是Y轴方向由负的值向正值变化,即对应如下代码

 if(animType == AnimType.DOWN){                startVal = -(0.1f + (getChildCount() - 1 - i) / 20f);}


另外代码中之所以会出现0.1f和i / 20f,是因为这里平移的是父容器高度的百分比,而i / 20f是为了让距离聚合中心远的控件直接的边距更大,这样更有离散聚合的效果。


3、优化

最后为了防止在当前动画还未执行完毕,又调用执行动画的方法,我们需要进行优化,这里我们加了一个名为mIsRunning的标记,另外我们还需要给最后一个子控件执行的动画添加监听事件,在最后一个动画执行完毕后将标记复原

/**     * 开始动画(补间动画)     */    public void startTweenAnim(@NonNull AnimType animType){        //如果正在执行就不再执行动画        if(mIsRunning){            return;        }        mIsRunning = true;        float startVal;        for (int i = 0; i < getChildCount(); i++) {            View childView = getChildAt(i);            startVal = 0.1f + i / 20f;            if(animType == AnimType.DOWN){                startVal = -(0.1f + (getChildCount() - 1 - i) / 20f);            }            TranslateAnimation animation=new TranslateAnimation(RELATIVE_TO_PARENT,0,RELATIVE_TO_PARENT,0,RELATIVE_TO_PARENT                    ,startVal ,RELATIVE_TO_PARENT,0);            animation.setDuration(700);//设置单次动画的重复时间            animation.setFillAfter(false);//设置动画结束后是否保持结束时的状态,默认为false            childView.startAnimation(animation);            //最后一个控件的动画添加监听事件            if(i == getChildCount() - 1){                animation.setAnimationListener(new Animation.AnimationListener() {                    @Override                    public void onAnimationStart(Animation animation) {
}
@Override public void onAnimationEnd(Animation animation) { //最后一个子控件的动画执行完毕了,将动画状态设置为没有动画 mIsRunning = false; }
@Override public void onAnimationRepeat(Animation animation) {
} }); } } }


源码地址:

https://gitee.com/itfitness/animatio-layout

浏览 63
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报