android:一個絢麗的注冊動畫

1、前言

本文github地址:https://github.com/qike2015/SignUpAnimation

在網(wǎng)站上看到一個很絢麗的注冊設計,先看下原設計效果:


image

下面是我實現(xiàn)的效果:

本文講解如何通過屬性動畫實現(xiàn)該效果。

動畫分析

整個動畫流程分成下面三部分來單獨實現(xiàn):

  1. 注冊按鈕點擊后的擴散動畫
  2. 網(wǎng)絡請求動畫
  3. 主頁面動畫

擴散動畫:當用戶點擊注冊按鈕后,整個按鈕呈圓形擴散直至鋪滿整個屏幕。

網(wǎng)絡請求動畫可以分為以下幾個部分:

  • signUp文字入場動畫:文字從下往上平移,同時播放縮放動畫,并且透明度逐漸加深。
  • 白線延長動畫,線條向右延伸,
  • success文字入場動畫,同時伴隨sign up文字的出場動畫,由左往右移動與sign up碰撞后減速停止,sign up向右移動并消失,倆個文字透明度皆發(fā)生變化。

請求網(wǎng)絡動畫播放成功后跳轉(zhuǎn)到主頁面,主頁的Tab欄由鋪滿整個屏幕逐漸變小到原始高度,并且Tab欄的倆個菜單按鈕透明度也發(fā)生變化。

2、注冊按鈕后的擴散動畫

點擊注冊按鈕后,顯示動畫播放view,開始播放縮放動畫。

整個縮放動畫就是一個圓形的view的放大動畫,將該view的背景設置為shape即可實現(xiàn)圓形效果。

圓形view的背景代碼:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <corners android:radius="180dp"/>
    <solid android:color="@color/colorPrimary"/>
</shape>

擴散動畫代碼:

 public static void spreadAni(View target, float endScale, SimpleAnimatorListener endListener)
    {
        ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(target, "ScaleX", endScale);
        scaleXAnimator.setInterpolator(new AccelerateInterpolator());

        ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(target, "ScaleY", endScale);
        scaleYAnimator.setInterpolator(new AccelerateInterpolator());

        AnimatorSet animSet = new AnimatorSet();
        animSet.play(scaleXAnimator).with(scaleYAnimator);
        animSet.setDuration(500);
        animSet.start();

        animSet.addListener(endListener);
    }

整個擴散(放大)動畫分成倆個屬性動畫,分別播放view在x方向和y方向的縮放動畫,該動畫最重要的地方在于計算最終放大比例,因為我們在布局文件中,縮放view的位置并沒有在整個動畫的正中間,還是向上偏移了一點,所以最終縮放值在計算結(jié)果的基礎上加1,否則動畫結(jié)束后背景顏色無法鋪滿整個屏幕:

    //計算擴散動畫最終放大比例
    private float getScale()
    {
        //原始擴散圓的直徑
        int orgWidth = v_spread.getMeasuredWidth();

        int width = getMeasuredWidth();
        int height = getMeasuredHeight();

        //擴散圓最終擴散的圓的半徑
        float finalDiameter = (int) (Math.sqrt(width * width + height * height));

        //因為圓未居中,所以加1
        return finalDiameter / orgWidth + 1;
    }

3、網(wǎng)絡請求動畫

擴散動畫播放結(jié)束后開始播放網(wǎng)絡請求動畫。整個過程分成三部分,下面分別講解實現(xiàn)方法。

3.1 signUp入場動畫文字

擴散動畫后結(jié)束后緊接著播放singUp的入場動畫,給動畫設置監(jiān)聽,在監(jiān)聽的onAnimationEnd(Animator animation)中開始入場動畫。

入場動畫代碼:


    /**
     * sign up文字入場動畫
     *
     * @param target      需要播放動畫的view
     * @param endListener 動畫監(jiān)聽
     */
    public static void signUpTextInAni(View target, SimpleAnimatorListener endListener)
    {
        target.setVisibility(View.VISIBLE);

        int targetHeight = target.getMeasuredHeightAndState();

        ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, "ScaleX", 0.75f, 0.87f, 1f, 1.1f, 1.0f);
        ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, "ScaleY", 0.75f, 0.87f, 1f, 1.1f, 1.0f);
        ObjectAnimator translationAni = ObjectAnimator.ofFloat(target, "TranslationY", targetHeight * 0.8f, -targetHeight * 0.2f, 0);
        ObjectAnimator alphaAni = ObjectAnimator.ofFloat(target, "Alpha", 0.5f, 1.0f);

        AnimatorSet animatorSet = new AnimatorSet();

        animatorSet.playTogether(scaleX, scaleY, translationAni, alphaAni);
        animatorSet.setDuration(2000);
        animatorSet.start();

        animatorSet.addListener(endListener);
    }

動畫開始播放時,將signUp文字(簡稱注冊文字,下同)顯示,通過AnimatorSetplayTogether()方法同上開啟四格動畫,即注冊文字的縮放動畫(x、y方向)、Y方向的平移動畫,透明度提升動畫。其中,縮放動畫從0.75倍放大到1.1倍大小后再縮放回原始大小(1.0倍),這樣實現(xiàn)一個放大膨脹然后再輕微反彈縮小到原始大小的效果。平移動畫類似,上升后再反彈下沉一定高度。具體變化值詳見代碼。


3.2 白線延長動畫

注冊文字入場動畫播放動畫結(jié)束后開始白色線條的延長動畫。這個動畫就是線條在X方向的縮放:

    public static void lineExpendAni(View target, SimpleAnimatorListener endListener)
    {
        target.setVisibility(View.VISIBLE);

        ObjectAnimator animator = ObjectAnimator.ofFloat(target, "ScaleX", 0, 0.6f, 0.9f, 1.0f);
        animator.setDuration(1500);
        animator.setInterpolator(new DecelerateInterpolator());
        target.setPivotX(0);
        animator.start();

        animator.addListener(endListener);
    }

利用setPivotX(0)方法把線條X方向的中心點(可理解為縮放的起始點,動畫將以該坐標為中線開始輻射,默認為view的中線點)設置0,這樣擴大動畫只會向一個方向發(fā)生,即可實現(xiàn)線條延長效果。動畫播放數(shù)值"0, 0.6f, 0.9f, 1.0f"并不是等差排列,還是越來越小,這樣即可實現(xiàn)減速效果(根據(jù)差值的縮小梯度絕對減速度的變化值)。


3.3 success文字入場動畫

   public static void successInAni(View success, View signUpView, SimpleAnimatorListener endListener)
    {
        success.setVisibility(View.VISIBLE);

        int durationTime = 1000;

        int width = success.getMeasuredWidth();

        ObjectAnimator successTranslationAni = ObjectAnimator.ofFloat(success, "TranslationX", width * -1.2f, width * -0.2f, 0);
        ObjectAnimator successAlphaAni = ObjectAnimator.ofFloat(success, "Alpha", 0.1f, 1.0f, 1.0f);

        ObjectAnimator signUpTranslationAni = ObjectAnimator.ofFloat(signUpView, "TranslationX",  0, width * 0.75f, width * 1.5f);
        signUpTranslationAni.setInterpolator(new AccelerateInterpolator());
        ObjectAnimator signUpAlphaAni = ObjectAnimator.ofFloat(signUpView, "Alpha", 1.0f, 1.0f, 0.4f, 0.0f);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(successTranslationAni, successAlphaAni, signUpTranslationAni, signUpAlphaAni);
        animatorSet.setDuration(durationTime);
        animatorSet.start();

        animatorSet.addListener(endListener);
    }

success文字(成功文字)的入場動畫包含倆組動畫:

  • 成功文字入場
  • 注冊文字出場

倆組動畫相互對應,即X方向的平移和透明度的增減。動畫的播放值代碼寫得很清楚,這里就不在累贅復述了。

4、主頁動畫

我們可動畫播放view設置一個自定義監(jiān)聽事件,當成功文字播放完成后,回調(diào)給activity。當動畫結(jié)束后,跳轉(zhuǎn)到主頁面。

主頁顯示后,播放動畫,動畫包含倆個動畫,先看代碼:

{
        ValueAnimator valueAnimator = ValueAnimator.ofInt(rl_title.getHeight(), DensityUtils.dp2px(this, 50));
        valueAnimator.setInterpolator(new AccelerateInterpolator());

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
        {
            @Override
            public void onAnimationUpdate(ValueAnimator animation)
            {
                rl_title.getLayoutParams().height = (int) animation.getAnimatedValue();
                rl_title.requestLayout();
            }
        });

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(valueAnimator,
                ObjectAnimator.ofFloat(iv_me, "Alpha", 0.1f, 1.0f),
                ObjectAnimator.ofFloat(iv_menu, "Alpha", 0.1f, 1.0f));
        animatorSet.setDuration(1200);
        animatorSet.start();
    }

代碼中:我們利用一個ValueAnimator實現(xiàn)tabView(rl_title)的高度收縮動畫,rl_title的起始高度鋪滿整個屏幕,最后高度變?yōu)?0dp收縮到屏幕頂部,同時倆個按鈕 iv_me 、iv_menu透明度加深。

ValueAnimator通過addUpdateListener設置一個數(shù)值變化監(jiān)聽,根據(jù)動畫計算的當前值通過布局參數(shù)動態(tài)設置rl_title的高度。

5、結(jié)束

最后奉上源碼下載地址http://download.csdn.net/detail/q649381130/9621869

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容