Android立體旋轉動畫實現與封裝(支持以X、Y、Z三個軸為軸心旋轉)

来源:http://www.cnblogs.com/popfisher/archive/2016/07/18/5679847.html
-Advertisement-
Play Games

本文主要介紹Android立體旋轉動畫,或者3D旋轉,下圖是我自己實現的一個界面 立體旋轉分為以下三種: 1. 以X軸為軸心旋轉 2. 以Y軸為軸心旋轉 3. 以Z軸為軸心旋轉--這種等價於android預設自帶的旋轉動畫RotateAnimation 實現立體旋轉核心步驟: 1. 繼承系統Anim ...


本文主要介紹Android立體旋轉動畫,或者3D旋轉,下圖是我自己實現的一個界面

 

立體旋轉分為以下三種:

  1. 以X軸為軸心旋轉

  2. 以Y軸為軸心旋轉

  3. 以Z軸為軸心旋轉--這種等價於android預設自帶的旋轉動畫RotateAnimation

 

實現立體旋轉核心步驟:

  1. 繼承系統Animation重寫applyTransformation方法

    通過applyTransformation方法的回調參數 float interpolatedTime, Transformation t 來控制旋轉動畫

    interpolatedTime 用來計算旋轉角度而 用來控制變換矩陣從而實現圖像的旋轉

  2. android.graphics.Camera控制旋轉演算法

    Camera可以對圖像執行一些比較複雜的操作--旋轉,綻放,與Matrix一起實現圖像的傾斜

 

核心代碼封裝:Rotate3dAnimation

package rotateanim.example.com.androidrotateanim;

import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.graphics.Camera;
import android.graphics.Matrix;

/**
 * An animation that rotates the view on the X,Y,Z axis between two specified angles.
 * This animation also adds a translation on the Z axis (depth) to improve the effect.
 */
public class Rotate3dAnimation extends Animation {
    public static final Byte ROTATE_X_AXIS = 0x00;
    public static final Byte ROTATE_Y_AXIS = 0x01;
    public static final Byte ROTATE_Z_AXIS = 0x02;
    private final float mFromDegrees;
    private final float mToDegrees;
    private final float mCenterX;
    private final float mCenterY;
    private final float mDepthZ;
    private final boolean mReverse;
    private Camera mCamera;
    private Byte mRotateAxis;  // 0:X軸  1:Y軸  2:Z軸

    /**創建3D旋轉動畫
     * @param fromDegrees the start angle of the 3D rotation
     * @param toDegrees the end angle of the 3D rotation
     * @param centerX the X center of the 3D rotation
     * @param centerY the Y center of the 3D rotation
     * @param depthZ the Z depth of the 3D rotation
     * @param rotateAxis the rotate axis of the 3D rotation
     * @param reverse true if the translation should be reversed, false otherwise
     */
    public Rotate3dAnimation(float fromDegrees, float toDegrees,
            float centerX, float centerY, float depthZ, Byte rotateAxis, boolean reverse) {
        mFromDegrees = fromDegrees;
        mToDegrees = toDegrees;
        mCenterX = centerX;
        mCenterY = centerY;
        mDepthZ = depthZ;
        mRotateAxis = rotateAxis;
        mReverse = reverse;
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        mCamera = new Camera();
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final float fromDegrees = mFromDegrees;
        float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);

        final float centerX = mCenterX;
        final float centerY = mCenterY;
        final Camera camera = mCamera;

        final Matrix matrix = t.getMatrix();
        // 將當前的攝像頭位置保存下來,以便變換進行完成後恢覆成原位
        camera.save();
        if (mReverse) {
            // z的偏移會越來越大。這就會形成這樣一個效果,view從近到遠
            camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
        } else {
            // z的偏移會越來越小。這就會形成這樣一個效果,我們的View從一個很遠的地方向我們移過來,越來越近,最終移到了我們的視窗上面
            camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
        }
        // 是給我們的View加上旋轉效果,在移動的過程中,視圖還會以XYZ軸為中心進行旋轉。
        if (ROTATE_X_AXIS.equals(mRotateAxis)) {
            camera.rotateX(degrees);
        } else if (ROTATE_Y_AXIS.equals(mRotateAxis)) {
            camera.rotateY(degrees);
        } else {
            camera.rotateZ(degrees);
        }

        // 這個是將我們剛纔定義的一系列變換應用到變換矩陣上面,調用完這句之後,我們就可以將camera的位置恢復了,以便下一次再使用。
        camera.getMatrix(matrix);
        // camera位置恢復
        camera.restore();

        // 下麵兩句是為了動畫是以View中心為旋轉點
        matrix.preTranslate(-centerX, -centerY);
        matrix.postTranslate(centerX, centerY);
    }
}

 

Rotate3dAnimation使用:跟普通動畫使用沒區別,設置給一個View對象,啟動動畫就搞定

mRotateImgv就是需要旋轉的View對象

// 以X軸為軸心旋轉
private void rotateOnXCoordinate() {
    float centerX = mRotateImgv.getWidth() / 2.0f;
    float centerY = mRotateImgv.getHeight() / 2.0f;
    float depthZ = 0f;
    Rotate3dAnimation rotate3dAnimationX = new Rotate3dAnimation(0, 180, centerX, centerY, depthZ, Rotate3dAnimation.ROTATE_X_AXIS, true);
    rotate3dAnimationX.setDuration(1000);
    mRotateImgv.startAnimation(rotate3dAnimationX);
}

// 以X軸為軸心旋轉
private void rotateOnYCoordinate() {
    float centerX = mRotateImgv.getWidth() / 2.0f;
    float centerY = mRotateImgv.getHeight() / 2.0f;
    float centerZ = 0f;

    Rotate3dAnimation rotate3dAnimationX = new Rotate3dAnimation(0, 180, centerX, centerY, centerZ, Rotate3dAnimation.ROTATE_Y_AXIS, true);
    rotate3dAnimationX.setDuration(1000);
    mRotateImgv.startAnimation(rotate3dAnimationX);
}

// 以Z軸為軸心旋轉---等價於普通平面旋轉動畫
private void rotateAnimHorizon() {
    float centerX = mRotateImgv.getWidth() / 2.0f;
    float centerY = mRotateImgv.getHeight() / 2.0f;
    float centerZ = 0f;

    Rotate3dAnimation rotate3dAnimationX = new Rotate3dAnimation(180, 0, centerX, centerY, centerZ, Rotate3dAnimation.ROTATE_Z_AXIS, true);
    rotate3dAnimationX.setDuration(1000);
    mRotateImgv.startAnimation(rotate3dAnimationX);

    // 下麵是使用android自帶的旋轉動畫
    // RotateAnimation rotateAnimation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    // rotateAnimation.setDuration(1000);
    // mRotateImgv.startAnimation(rotateAnimation);
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在啟動篇中我們詳細分析了TaintDroid對DVM方法參數和方法變數的變數級污點跟蹤機制,現在我們將繼續分析TaintDroid對類的靜態域、實例域以及數組的污點跟蹤。 ...
  • DBFarmer是PowerFramework資料庫管理工具的集合。 可以進行對象的存儲,添加了setter和getter的參數會被收錄到資料庫中,每個參數作為一個項,int類型的id或_id會被作為primary key。 資料庫名為DBFarmer.db,在項目目錄下。每個對象的表名為類的全名替 ...
  • 鎖屏作為一種黑白屏時代就存在的手機功能,至今仍發揮著巨大作用,特別是觸屏時代的到來,鎖屏的功用被髮揮到了極致。多少人曾經在無聊的時候每隔幾分鐘劃開鎖屏再關上,孜孜不倦,其酸爽程度不亞於捏氣泡膜。 ...
  • 1Add JAR 從Eclipse的現有所有工程中,添加jar包到該工程下 2Add External JARs 從Eclipse外的其他的位置,添加jar包到該工程下 3Add Variable 增加一個變數 4Add Library 增加一個庫 5Add Class Folder 從Eclips ...
  • /etc/hosts 把host 複製到桌面 修改 然後 替換原來的 ...
  • 一,工程圖。 二,代碼。 AppDelegate.m ...
  • 縱觀移動市場,一款移動app,要想長期在移動市場立足,最起碼要包含以下幾個要素:實用的功能、極強的用戶體驗、華麗簡潔的外觀。華麗外觀的背後,少不了美工的辛苦設計,但如果開發人員不懂得怎麼合理展示這些設計好的圖片,將會糟蹋了這些設計,功虧一簣。 比如下麵張圖片,本來是設計來做按鈕背景的: button ...
  • 學習知識:界面組成、事件監聽器 界面組成 1.用戶界面的基本組件叫做View,都是繼承android.view.View類,Android裡面預定義很多基本的界面組件,比如 Button, CheckBox, ProgressBar and TextView,它們一般稱作組件或是部件(widgets ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...