1. 程式人生 > >Android 圖片彈跳動畫2

Android 圖片彈跳動畫2

在上一篇博文Android 圖片彈跳動畫裡,我用兩種方法實現了一個彈跳的動畫,實現效果上篇博文裡面有,這裡就不再貼了,雖說是兩種方法,但實現機制是大同小異,核心思想就是遞迴的不斷啟動動畫,來實現View的上升和下降,後來發現還有另一種方法,不需要遞迴的去啟動多個動畫,只需要啟動一個動畫即可。

這裡核心思想是自定義Interpolator,也就是插值器,關於插值器是什麼網上有很多詳細的介紹,我們上篇博文也用到了,只不過用的是系統定義好的。這裡簡單說就是它不會改變動畫的執行順序,但可以改變動畫的執行效果,它的原理就是實現一個插值器的公共介面,完後具體實現getInterpolation方法,這個方法有一個引數是input,它表示了動畫執行的過程,它的值從0到1,在動畫執行過程中會不斷呼叫這個方法,並且input線性遞增,通過這個值,我們就可以根據自己動畫的函式來返回我們想要的效果。

在上篇博文中,我們說過這個動畫的幾個要點,這裡重新貼下:

1. 動畫彈起的高度越來越小,我這裡是第一次彈起螢幕的高度的1/2,第二次彈起1/4,第三次彈起1/8,以此類推

2. 我們將圖片的一次落下或彈起看成一次動畫,動畫的時間越來越短,假設第一次落下動畫需要1秒,那第一次彈起就需要1/2秒,第二次落下也是1/2秒,第二次彈起則需要1/4秒,以此類推

3. 下落的時候,速度越來越快,彈起的時候,速度越來越慢


其實Android本身已經寫好了一個彈起落下的Interpolator,叫BounceInterpolator,我們先簡單看看

public class BounceInterpolator implements Interpolator, NativeInterpolatorFactory {
    public BounceInterpolator() {
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public BounceInterpolator(Context context, AttributeSet attrs) {
    }

    private static float bounce(float t) {
        return t * t * 8.0f;
    }

    public float getInterpolation(float t) {
        // _b(t) = t * t * 8
        // bs(t) = _b(t) for t < 0.3535
        // bs(t) = _b(t - 0.54719) + 0.7 for t < 0.7408
        // bs(t) = _b(t - 0.8526) + 0.9 for t < 0.9644
        // bs(t) = _b(t - 1.0435) + 0.95 for t <= 1.0
        // b(t) = bs(t * 1.1226)
        t *= 1.1226f;
        if (t < 0.3535f) return bounce(t);
        else if (t < 0.7408f) return bounce(t - 0.54719f) + 0.7f;
        else if (t < 0.9644f) return bounce(t - 0.8526f) + 0.9f;
        else return bounce(t - 1.0435f) + 0.95f;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createBounceInterpolator();
    }
}
這裡我們要關注的就是getInterpolation這個方法,上面已經解釋過它的實現原理,我們來看看對應的圖


這是網上找的圖片,這裡x軸是時間,也就是上面提到的input,y軸是動畫的過程,對照上面的實現,我們可以看到t < 0.3535f時,是一個遞增的拋物線,在0.3535f時,y為1,也就是動畫第一次落下,而t < 0.7408f時,是一個先遞減,再遞增的拋物線,也就是彈起又落下,而t < 0.9644f類似的,再一次彈起又落下,最後的0.9644到1是最後一次彈起落下,至於這裡的函式為什麼這樣定義,說實話我沒看懂,物理渣傷不起,估計可能跟重力感應還多少有些聯絡,不管這些,物理不是我們研究的重點,我們自己來實現類似的。為了簡化問題,我們就以圖片彈起兩次為例進行說明,至於彈起三次、四次、五次,原理都是類似的。

我們將動畫過程進行分解,圖片彈起兩次,經歷了5個過程:

1. 圖片第一次落下,從螢幕的頂部出現,直到螢幕底部

2. 圖片第一次彈起,從螢幕的底部彈起到螢幕高度的1/2

3. 圖片第二次落下,從螢幕高度的1/2落下到螢幕底部

4. 圖片第二次彈起,從螢幕的底部彈起到螢幕高度的1/4

5. 圖片第三次落下,從螢幕高度的1/4落下到螢幕底部

按照上面提到的動畫的要點2,我們假設第一步花費時間為x,則第二步和第三步花費時間分別為x / 2,第四步和第五步花費時間分別為x / 4,則有公式:

x + x / 2 * 2 + x / 4 * 2 = 1

一元方程, x的值為 2 / 5

有了這個值後,我們就可以得到類似上圖的一個分段拋物線,之前有免費畫拋物線的軟體,現在開始收費了,其它軟體畫有點麻煩,所以我就用文字描述下,對應上面動畫過程的五步:
1. 在x軸的【0,2/5】這個區間,是一個遞增的拋物線,y從0變為1,也就是圖片第一次落下,我們可以得到拋物線的函式為 y = 25 / 4 * x * x(至於這個函式怎麼來的,可能需要大家懂一點拋物線的知識,我們初中還是高中肯定學過,只不過時間長了忘了,我們可以先回憶一個簡單的拋物線,y = x * x,也就是AccelerateInterpolator的實現中用到的,x軸從0開始勻速到1,y軸的值從0開始加速到1,我們這裡只不過是將x的區間換成了【0,2/5】而已)

2. 在x軸的【2/5,3/5】這個區間,是一個遞減的拋物線,y從1變為1/2,也就是圖片第一次彈起

3. 在x軸的【3/5,4/5】這個區間,是一個遞增的拋物線,y從1/2變為1,也就是圖片第二次落下,2、3步是同一個拋物線,函式為y = 1/ 2 + 25 / 2 * (x - 3 / 5) * (x - 3 / 5)

4. 在x軸的【4/5,9/10】這個區間,是一個遞減的拋物線,y從1變為3/4,也就是圖片的第二次彈起

5. 在x軸的【9/10,1】這個區間,是一個遞增的拋物線,y從3/4變為1,也就是圖片的第三次落下,4、5步是同一個拋物線,函式為y = 3/4 + 25 * (x - 9/10) * (x - 9/10)

通過上面的分析,我們實現自己的插值器就很簡單了

public class JumpInterpolator implements TimeInterpolator {

    @Override
    public float getInterpolation(float input) {

        if (input <= 2/5f) {
            return 25 / 4f * input * input;
        } else if (input <= 4/5f) {
            return 1 / 2f + 25 / 2f * (input - 3 / 5f) * (input - 3 / 5f);
        } else {
            return 3 / 4f + 25 * (input - 9 / 10f) * (input - 9 / 10f);
        }

    }
}

看下MainActivity的實現

public class MainActivity extends Activity {
    private ImageView jump;
    private int mHeight;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        jump = (ImageView) findViewById(R.id.move);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

        if (hasFocus) {
            Rect outRect = new Rect();
            getWindow().findViewById(Window.ID_ANDROID_CONTENT).getDrawingRect(outRect);
            mHeight = outRect.height();

            beginTransAnimation();
        }
    }

    private void beginTransAtranslationYnimation() {
        ObjectAnimator animator = ObjectAnimator.ofFloat(jump, "translationY", -mHeight, 0);
        animator.setInterpolator(new JumpInterpolator());
        animator.setDuration(5000);
        animator.start();
    }
}

在頁面載入完成時,我們首先獲取螢幕的高度,並賦值給mHeight變數,完後啟動動畫,這裡動畫還是用的屬性動畫,指定動畫變化的部分為translationY,也就是y軸的座標,初始值為-mHeight,也就是初始時圖片的下邊緣跟螢幕的上邊緣重合(所以初始時看不到圖片),而動畫的終點為0,也就是圖片完全顯示在螢幕中,這裡最重要的是我們指定了插值器為我們剛剛定義的JumpInterpolator,完後指定動畫時間,最後啟動動畫即可,比較上一篇部落格的兩種實現方式,我們發現過程還是簡化了許多,沒有遞迴,也不會多次啟動動畫,一次就搞定。 原始碼下載

相關推薦

Android 圖片彈跳動畫2

在上一篇博文Android 圖片彈跳動畫裡,我用兩種方法實現了一個彈跳的動畫,實現效果上篇博文裡面有,這裡就不再貼了,雖說是兩種方法,但實現機制是大同小異,核心思想就是遞迴的不斷啟動動畫,來實現View的上升和下降,後來發現還有另一種方法,不需要遞迴的去啟動多個動畫,只需要

Android 圖片彈跳動畫

這幾天看到一個小動畫,覺得有點意思,就自己實現來看看,先看效果圖 OK,這個效果基本功能就是,一個圖片,從頂部掉下來,完後彈幾下,再停止,實現起來還是比較簡單的,不過也走了點小彎路,這裡記錄下。 有段時間做自定義控制元件比較多,有點中毒了,看到任何效果第一個先想到自定義

android 圖片旋轉動畫

// 旋轉1: iv_state.setPivotX(iv_state.getWidth()/2); iv_state.setPivotY(iv_state.getHeight()/2);//支點在圖

Android中具有動畫效果的圖片資源

在一些場景下,圖片需要具有動畫效果。當你想顯示一個由多張圖片組成的loading動畫,或者一個圖示切換過程,就需要到具有動畫效果的圖片了。Android提供了幾種方式實現動畫圖片。 下面的是個示例: 第一種方式是使用Animation Drawable,這是通過建立多張靜態

Android回收AnimationDrawable動畫的每一幀的圖片資源,釋放記憶體資源

/** * 回收每一幀的圖片,釋放記憶體資源  * 取出AnimationDrawable中的每一幀逐個回收,並且設定Callback為null */ private static void tryRecycleAnimationDrawable(AnimationDra

Android圖片編輯器實踐指南-2.圖片視訊選擇器(1)

本篇將會介紹媒體選擇器,包括圖片選擇器和視訊選擇器,更進一步的擴充套件到根據目錄顯示不同的圖片。 2.1 圖片選擇器 具體開發圖片選擇器之前,先說明一下MediaStore類,之後所有的圖片操作,查詢都和這個類有關係。官網上對這個類的定義為: The Media

Android使用shape製作圓形控制元件及新增彈跳動畫

前言:我們在很多時候都需要在res/drawable資料夾下建立相應的xml檔案來為控制元件新增一些樣式效果,比如按鈕按下時的按鈕樣式變化、或者指定按鈕的一些邊框樣式、或者為常用的EditText、TextView、ImageView、ImageButton等等新增一些樣

android圖片點選放大動畫,並遮擋旁邊的控制元件

首先是點選放大 可以使用android自帶的縮放動畫,因為要遮蓋其他控制元件,就需要控制元件處在最上層,這裡需要呼叫bringTofront方法 @Overridepublic boolean onTouch(View v, MotionEvent event) {// T

Android逐幀動畫,逐幀動畫載入圖片過多時OOM異常的解決和替代方法

1.首先新增逐幀動畫 播放逐幀動畫,在工程中res目錄下建立一個anim資料夾,新增動畫anim_welcome.xml檔案如下: <?xml version="1.0" encoding="utf-8"?> <animation-li

Android中使用多張圖片組成動畫 AnimationDrawable

imageView =(ImageView)findViewById(R.id.imageView);//放置的ImageView控制元件 //設定動畫背景 imageView.setBackgroundResource(R.drawable.animation_list);//其中R.drawable

修改Android開機圖片動畫、聲音

二、修改第二張圖片  方法一:  在window下的操作:  1 在 Widows 環境中建立資料夾:bootanimation  2 在bootanimation資料夾中建立子資料夾:   part0   part1   然後將一批.png檔案拷貝到資料夾part0裡面,part1中暫時不放圖片檔案  3

android圖片閃爍或幀動畫

remote_recording_transition.xml 檔案 <?xml version="1.0" encoding="utf-8"?> <animation-list     xmlns:android="http://schemas.andr

Android實用檢視動畫及工具系列之九:漂亮的圖片選擇器,高效能防崩潰圖片選擇工具

public class MainActivity extends AppCompatActivity { private Button btn1, btn2; private TextView tv1; private ArrayList<String> path =

android播放多張圖片形成動畫 (幀動畫)

在andriod裡可以逐幀的播放圖片,然後產生一種動態的效果,準備好幾張連續的圖片,然後在於源程式res資料夾下建立anim資料夾,然後新建一個XML: 複製內容到剪貼簿 程式碼: <?xml version="1.0" encoding="utf-8"?>

android圖片漸隱漸現動畫效果

    最近專案中需要用到一個過渡動畫,就是一個圖片漸隱漸現,然後重複五次後過渡動畫消失,首先說下我的思路,一個timer,重複執行,然後執行的時候肯定要不斷呼叫顯示、隱藏動畫。其中定時器每次重複的時間是動畫顯示(或隱藏)的時間 public class Mai

android 圖片雙擊放大倍數的算法

ack 過大 保留 trac scale max nbsp pos ini 圖片雙擊放大倍數和圖片大小、顯示圖片的view大小。及圖片當前的scale大小均有關系。 為了避免圖片放大過大。設置了一個放大倍數的最大限制SCALE_LIMIT,眼下該值為4. 詳細算法例

android縮放動畫的兩種實現方法

get odi omx rac tor Coding eight rpo odin 在android開發。我們會常常使用到縮放動畫,普通情況下縮放動畫有兩種實現方式。一種是直接通過java代碼去實現,第二種是通過配置文件實現動畫,以下是兩種動畫的基本是用法: Ja

FaceBook推出的Android圖片載入庫-Fresco

一次 人員 的人 java代碼 jpeg markdown 開發 改變 水平 歡迎關註ndroid-tech-frontier開源項目,定期翻譯國外Android優質的技術、開源庫、軟件架構設計、測試等文章 原文鏈接:Intro

Android圖片左右移動

android圖片左右移動這個博文,是在上一篇的基礎上修改而成,這次是控制圖片左右移動,上下移動類似就不在寫了 package com.yuanlp.testimage; import android.graphics.Bitmap; import android.graphics.BitmapFac

應用啟動時將白屏背景替換成圖片/顏色/動畫等 僅供參考

lns cte star cat 16px 繼承 encoding 默認啟動 drawable 1.創建自己的主題樣式(style) 在vules資源目錄下的style中創建一個樣式 <style name="MyTheme" parent="Theme