属性动画案例一(基础动画与飘心动画)

之前写过一个 基本属性动画 的简单介绍,这里再简单试用一下。属性动画的案例有很多很多都是特别炫的,其实重点还是思路,这里就提供一些属性动画的思路,思路可能很粗糙,但是效果实现了~

先看一下今天实现的第一种效果。


setAnim.gif

这里是两张图片,用动画集合简单的实现了一个动画效果。分析一下需要用到的动画,商品页面有:透明动画,旋转动画,还有一个缩放动画,暂时就能看出这么多,看一下代码实现。

        //透明度动画
        ObjectAnimator firstAlphaAnim = ObjectAnimator.ofFloat(first_view, "alpha", 1.0f, 0.7f);
        firstAlphaAnim.setDuration(300);
        //旋转动画1
        ObjectAnimator firstRotationXanim = ObjectAnimator.ofFloat(first_view, "rotationX", 0f,20f,0f);
        firstRotationXanim.setDuration(600);
        //缩放动画
        ObjectAnimator firstScaleXAnim = ObjectAnimator.ofFloat(first_view, "ScaleX", 1.0f, 0.8f);
        firstScaleXAnim.setDuration(300);
        ObjectAnimator firstScaleYAnim = ObjectAnimator.ofFloat(first_view, "ScaleY", 1.0f, 0.8f);
        firstScaleYAnim.setDuration(300);
        AnimatorSet set = new AnimatorSet();
        //一起执行
        set.playTogether(
                firstScaleXAnim,
                firstScaleYAnim,
                firstAlphaAnim,
                firstRotationXanim
        );
        set.start();
setAnim1.gif

这里发现,应该是还少一个平移动画,才能让view贴到屏幕上边。由于刚才缩放高度减少了0.2*view的高度,上下各0.1,所以我们需要向上平移0.1个控件的高度。

        //由于缩放造成离顶部有一个距离,需要平移
        ObjectAnimator firstTranslationYAnim = ObjectAnimator.ofFloat(first_view, "translationY", 0f, -0.1f*first_view.getHeight());
        firstTranslationYAnim.setDuration(300);
setAnim2.gif

好了,一个view解决了,剩下就是规格页面的一个显示并平移,规格页面初始是不显示的,在商品页面动画开始的时候,显示规格页面,并从自己的底部移动到自己原来的位置。

        //第二个view和第一个view动画同时开始执行
        ObjectAnimator secondTranslationYAnim = ObjectAnimator.ofFloat(second_view, "translationY", second_view.getHeight(), 0f);
        secondTranslationYAnim.setDuration(300);
        secondTranslationYAnim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                second_view.setVisibility(View.VISIBLE);
                bt.setClickable(false);
                bt1.setClickable(false);
            }
        });

最后大功告成。基本的属性动画又使用了一次,是不是不过瘾,发现这个Demo 有两个按钮,之前一直都是点的 显示 按钮会出现基础动画的使用,那个赞一个是什么鬼。

Anim3.gif

这种常见的刷鲜花效果,这里依旧是属性动画实现的,还记得在 基本属性动画中说过的一个估值器,可以让View以抛物线的轨迹移动,这里也是用到了估值器,一起来看一下怎么实现的把~
首先我们在点击按钮是需要添加心图片,并简单的做了内存优化。一些值的初始化就在 源码 中看吧

    //点击按钮时调用
    public void addLoveIcon(){
        final ImageView iv ;
        //添加心形,并开始执行动画
        iv= (ImageView) Recycle();
        iv.setImageDrawable(drawables[random.nextInt(3)]);
        //将iv添加到父容器底部、水平居中位置
        iv.setLayoutParams(params);
        addView(iv);
        //开始属性动画:平移、透明度渐变、缩放动画
        AnimatorSet set = getAnimator(iv);

        //监听动画执行完毕,将iv移除或者复用
        set.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                removeView(iv);
            }
        });
        set.start();
    }

    List<View> list=new ArrayList<>();
    //重新removeView将要删除的View保存起来
    @Override
    public void removeView(View view) {
        list.add(view);
        super.removeView(view);
    }
    //添加view的时候先看有没有之前保存的imageView
 private View Recycle() {
        if (list.isEmpty()) {
            ImageView iv = new ImageView(getContext());
//            {//固定位置
//              startX=(mWidth - dWidth) / 2;
//
//            }
            {//随机位置
                startX = random.nextInt(mWidth);
                iv.setX(startX);
                iv.setY(mHeight - dHeight);
            }
            return iv;
        } else {
            View v = list.get(0);
            //这里是在复用的时候如果执行第一个缩放动画,位置会有问题,所以这里设置一下初始位置
//          {//固定位置
//              startX=(mWidth - dWidth) / 2;
//              v.setX(startX);
//              v.setY(mHeight - dHeight);
//          }
            {//随机位置
                startX = random.nextInt(mWidth);
                v.setX(startX);
                v.setY(mHeight - dHeight);
            }
            list.remove(v);
            return v;
        }
    }

这里的固定位置和随机位置是图片初始的位置,现在是随机位置,如果要使用固定为在需要将这里面代码重新注释,把随机位置的代码块注释掉,然后把源码 81行 82 行 params的设置解开。在添加的时候调用getAnimator()来设置imageView动画。

    // 得到一个iv的动画集合
    private AnimatorSet getAnimator(ImageView iv) {
        //平移、透明度渐变、缩放动画
        //1.alpha动画
        ObjectAnimator alpha = ObjectAnimator.ofFloat(iv, "alpha", 0.3f,1f);
        //2.缩放动画
        ObjectAnimator scaleX = ObjectAnimator.ofFloat(iv, "scaleX", 0.5f,1f);
        ObjectAnimator scaleY = ObjectAnimator.ofFloat(iv, "scaleY", 0.5f,1f);
        //三个动画同时执行
        AnimatorSet enter = new AnimatorSet();
        enter.setDuration(200);
        enter.playTogether(alpha,scaleX,scaleY);

        //设置平移的曲线动画---贝塞尔曲线
        ValueAnimator bezierAnimator = getBezierValueAnimator(iv);

        AnimatorSet set = new AnimatorSet();
        //按序列执行
        set.playSequentially(enter, bezierAnimator);
        //加速因子,使用插值器
        set.setInterpolator(interpolators[random.nextInt(4)]);
        set.setTarget(iv);
        return set;
    }

先执行原地的缩放,透明度变化的动画,再执行估值器的动画。

    //得到一个贝塞尔曲线动画
    private ValueAnimator getBezierValueAnimator(final ImageView iv) {
        //根据贝塞尔公式确定四个点(起始点p0,拐点1p1,拐点2p2,终点p3)
        PointF pointF0 = new PointF(startX, mHeight - dHeight);//屏幕宽度随机的为起点
        PointF pointF3 = new PointF(random.nextInt(mWidth), 0);
        PointF pointF1 = getPointF(1);
        PointF pointF2 = getPointF(2);
        //估值器Evaluator,来控制view的行驶路径(不断地修改point.x,point.y)
        BezierEvaluator evaluator = new BezierEvaluator(pointF1, pointF2);
        //属性动画不仅仅可以改变view的属性,还可以改变自定义的属性(比如Point)
        ValueAnimator animator = ValueAnimator.ofObject(evaluator, pointF0, pointF3);
        animator.addUpdateListener(new AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                PointF pointF = (PointF) animation.getAnimatedValue();
                iv.setX(pointF.x);
                iv.setY(pointF.y);
                iv.setAlpha(1 - animation.getAnimatedFraction());//1~0 百分比
            }
        });

        animator.setDuration(4000);
        return animator;
    }

这里是对 起点,终点,和两个控制点的初始化,这样就可以形成一个三阶贝塞尔曲线,这里会间接的把四个点传过去,在BezierEvaluator计算X,Y的值,直接套公式,通过监听获取返回的坐标值。
最后附上 源码

这里只是属性动画基本的一个使用,如果其中有错误还请指出,我会尽快修改文章,并改正自己的理解,谢谢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容