1. 程式人生 > >Android 動畫之屬性動畫- Interpolator(內插器)

Android 動畫之屬性動畫- Interpolator(內插器)

Android動畫系列:

介紹

對於Interpolator(內插器),寫過動畫的都不會陌生,其本身看做是一個時間計算器,用於定義動畫的執行的速率。

public class ValueAnimator extends Animator implements AnimationHandler.AnimationFrameCallback {

     ***            

    // The time interpolator to be used if none is set on the animation
    private static final TimeInterpolator sDefaultInterpolator =
            new AccelerateDecelerateInterpolator();
    /**
     * The time interpolator to be used. The elapsed fraction of the animation will be passed
     * through this interpolator to calculate the interpolated fraction, which is then used to
     * calculate the animated values.
     */
    private TimeInterpolator mInterpolator = sDefaultInterpolator;

    ***  

}

上面是ValueAnimator原始碼的一部分,在這裡可以清晰的看出來,在我們不為ValueAnimator設定Interpolator為AccelerateDecelerateInterpolator,也就是說系統預設是先加速後減速這樣一種動畫執行速率。

    LinearInterpolator ll = new LinearInterpolator();
    ObjectAnimator animator = ObjectAnimator.ofFloat(btnProperty, "rotation",
            0f, 360f);
    animator.setInterpolator(ll);
    animator.setDuration(5000);
    animator.setRepeatCount(ValueAnimator.INFINITE);

    ObjectAnimator animatorA = ObjectAnimator.ofFloat(btnPropertyA, "rotation",
            0f, 360f);

    animatorA.setRepeatCount(ValueAnimator.INFINITE);
    animatorA.setDuration(5000);

    animator.start();
    animatorA.start();

這裡寫圖片描述

先定義兩個Button,其中,btnProperty背景色設定為紅色,而btnPropertyA的背景色設定為藍色.對兩個Button分別定義了動畫,btnProperty的動畫的Interpolator設定為LinearInterpolator,即動畫的執行速率為勻速運動,而btnPropertyA的動畫的Interpolator設定未設定使用的是預設的。從實際執行的效果可以清晰的看出,剛開始時,btnProperty動畫執行速率快於btnPropertyA,隨著動畫的執行,btnPropertyA逐漸追上了btnProperty,在同一輪動畫時,它們同時處於結束位置。對於動畫的預設Interpolator為AccelerateDecelerateInterpolator,也就有了合理的解釋了。

原始碼分析

對於動畫的執行速率,Interpolator是怎麼計算的呢?先看Interpolator的原始碼:

public interface Interpolator extends TimeInterpolator {
}

public interface TimeInterpolator {
    /**
     * Maps a value representing the elapsed fraction of an animation to a value that represents
     * the interpolated fraction. This interpolated value is then multiplied by the change in
     * value of an animation to derive the animated value at the current elapsed animation time.
     */
    float getInterpolation(float input);
}

從Interpolator的原始碼可以看出,Interpolator其實就是一個空的介面,繼承與TimeInterpolator。再看看TimeInterpolator這個介面,其內只聲明瞭getInterpolation(float)這一個方法。傳入getInterpolation(float)方法的引數實際上是動畫的進度,其值在0和1之間,0表示動畫開始,1表示動畫結束。而其返回值是表示內插器計算出來的值,其可以小於0或者大於1。然後將內插值乘以動畫中屬性值的差量即為畫的當前屬性值。

剛才我們用到了LinearInterpolator,表示動畫勻速執行,下面看看勻速效果是怎麼現實的。

public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {

    public LinearInterpolator() {
    }

    public LinearInterpolator(Context context, AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return input;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createLinearInterpolator();
    }
}

從LinearInterpolator原始碼中可以看出,在getInterpolation(float input)方法中並沒有對input值做任何處理。由於input值是動畫執行的百分比,這個值是均勻的。故而LinearInterpolator計算出的內插值其實就是動畫執行的百分比,沒有啥變化。

public class AccelerateDecelerateInterpolator extends BaseInterpolator
        implements NativeInterpolatorFactory {
    public AccelerateDecelerateInterpolator() {
    }

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

    public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
    }
}

對於AccelerateDecelerateInterpolator而言,其getInterpolation(input)方法中對intput做了處理,下圖為其處理方式所對應的函式影象,從影象可以清晰的看出,內插值開始時增長趨勢很快,然後在減小。相對應內插值計算動畫屬性時,應該是起初動畫屬性值逐漸增大很快,然後增大趨勢減弱,意味著表現出來的動畫效果為先加速再減速。

這裡寫圖片描述

自定義Interpolator

1.自定義一個Interpolator,命名為MyInterpolator

public class MyInterpolator implements TimeInterpolator {
    @Override
    public float getInterpolation(float input) {
        float inter;
        inter = 1 - input * input;
        return inter;
    }
}animatorA

2.將animator的Interpolator設定為LinearInterpolator,而animatorA的設定為剛定義的MyInterpolator。

    LinearInterpolator ll = new LinearInterpolator();
    ObjectAnimator animator = ObjectAnimator.ofFloat(btnProperty, "rotation",
            0f, 360f);
    animator.setInterpolator(ll);
    animator.setDuration(5000);
    animator.setRepeatCount(ValueAnimator.INFINITE);

    ObjectAnimator animatorA = ObjectAnimator.ofFloat(btnPropertyA, "rotation",
            0f, 360f);
    animatorA.setInterpolator(new MyInterpolator());
    animatorA.setRepeatCount(ValueAnimator.INFINITE);
    animatorA.setDuration(5000);

    animator.start();
    animatorA.start();

這裡寫圖片描述

從效果圖上,可以看出btnPropertyA的實際動畫效果是倒著轉的,而且是先加速後減速,為啥會出現這種情況呢?百思不得其解,前面已經說過btnPropertyA的動畫的內插器為MyInterpolator,那麼此種效果必然與內插器有關。先不管效果到底是為啥,先MyInterpolator中,從1 - input * input的函式影象和實際值,來看看getInterpolation(input)的處理結果。

  1. 函式影象
    下圖為在0-1之間的函式影象,從函式影象可以看出,其函式值先加速後減速。

這裡寫圖片描述

  1. 實際值
input getInterpolation
0 1
0.1 0.99
0.2 0.96
0.4 0.86
0.6 0.64
0.8 0.36
0.9 0.19
1.0 0

從函式影象和實際值的差值,我們清楚的看到,動畫屬性值的變化幅度先逐漸變大然後再逐漸減少的,這也能夠解釋動畫的執行速率問題了。

接下來看看動畫為啥倒轉呢。在宣告動畫時,開始旋轉角度為0f,結束的旋轉角度為360.0f,也就是動畫的實際效果是旋轉一週,這個沒有問題,實際上也就是選擇一週的。而動畫的旋轉角度差值為360.0f。假如動畫的執行百分比為0.1時,MyInterpolator內插器計算出來的內插值為0.99f.
前面說過將內插值乘以動畫中屬性值的差量即為畫的當前屬性值,此時動畫當前的屬性值應為356.4f,也就是此時,btnPropertyA旋轉了356.4。同理當動畫執行百分比為0.2時,btnPropertyA旋轉了345.6度。也就是btnPropertyA的動畫效果實際上是先旋轉到360度,然後慢慢旋轉到0度(初始位置)。這也就是btnPropertyA的動畫倒轉的原因。

也就是說動畫的屬性值的計算是由Interpolator和Evaluators共同計算出來的。當動畫開始以後,Interpolator先獲取動畫執行的百分比並計算出來內插值,Evaluators在獲取Interpolator計算出的內差值並在evaluate(float fraction, MyPoint pointStart, MyPoint pointEnd)內計算出動畫的屬性值。有說過fraction為動畫的執行的百分比,其實描述的並不準確,其實際值因為Interpolator計算出的內插值。既然瞭解到了Interpolator、Evaluators和動畫屬性值之間的計算關係,以後隨心所欲的自定義動畫了。

相關推薦

Android 動畫屬性動畫- Interpolator()

Android動畫系列: 介紹 對於Interpolator(內插器),寫過動畫的都不會陌生,其本身看做是一個時間計算器,用於定義動畫的執行的速率。 public class ValueAnimator extends Animator impleme

Android動畫屬性動畫基礎用法

在上一篇Android動畫基礎之補間動畫與逐幀動畫 ,我們複習了Android的基礎動畫Tweened Animation、Frame Animation,同時指出他們的缺陷,改變是View的顯示效果而不是View本身的屬性,還有我們不多不少會看多人家的APP有一些很酷炫的動畫效果,但是

Android 動畫屬性動畫

import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.app.Activity;

Android動畫屬性動畫(下)

前言        前面我們已經完整的講述了屬性動畫的實現,我們已經學會了怎麼實現動畫,如果沒有屬性我們也學會了怎麼新增屬性,還學習了用ValueAnimator來實現動畫。 Evaluator        這裡我們來學習剩下的屬性,首先我們來看看E

Android動畫屬性動畫(四)

一 前言       在《》、《Android屬性動畫之ObjectAnimator和AnimatorSet》兩篇文章中學習了ValueAnimator、ObjectAnimator、Animator

Android開發中屬性動畫(ObjectAnimator)中 (Time Interpolator )詳解

在 Android開發中,為了保持良好的互動體驗,我們經常會用到動畫來提升使用者體驗,而動畫中屬性動畫用的最多。 雖然動畫可以讓介面看起來不是那麼粗糙,但是很多時候僅僅只是勻速運動的動畫可能不足以描述一些我們想呈現給使用者的介面,比如模擬一個下落的小球,我們知道下落的小球並不是以勻速運動的,

Android 動畫動畫詳解屬性動畫(三)

大家好,在前兩篇中,我們介紹了Android的補間動畫和插值器,這一篇,我們來說下屬性動畫。 【Android 動畫】動畫詳解之補間動畫(一) 【Android 動畫】動畫詳解之插值器(二) 前言 通過前兩篇,我們已經熟悉了對View進行移動、縮放、旋轉和

Android - 動畫(幀動畫,補間動畫屬性動畫,以及

一: 動畫的分類 幀動畫 補間動畫 屬性動畫 二:解析 1. 幀動畫 (1)定義 這些圖片是將一些列的drawable組合在一起,進行連續的播放, 類似於以前電影源用膠捲進行動畫播放 (2)有圖有真相 (3)準備圖片 看著是不是還行,哈哈,

從零開始學Android自定義View動畫系列——屬性動畫(3)

屬性動畫對補間動畫進行了很大幅度的改進,之前補間動畫可以做到的屬性動畫也能做到,補間動畫做不到的現在屬性動畫也可以做到了。因此,今天我們就來學習一下屬性動畫的高階用法,看看如何實現一些補間動畫所無法實現的功能。 ValueAnimator的高階用法 補間

Android自定義view屬性動畫

Android 裡動畫是有一些分類的:動畫可以分為兩類:Animation 和 Transition;其中 Animation 又可以再分為 View Animation 和 Property Animation 兩類: View Animation 是純粹基於 framew

Android動畫學習(五)屬性動畫實現Tween的效果和高階屬性示例

一、基本介紹 Golang設計者為了程式設計方便,提供了一些函式,這些函式可以直接使用,我們稱為Go的內建函式。文件:https://studygolang.com/pkgdoc -> buil

Android動畫系列屬性動畫

> 原文首發於微信公眾號:jzman-blog,歡迎關注交流! 屬性動畫相較幀動畫和補間動畫更強大,幀動畫和補間動畫只能應用於 View 及其子類,而屬性動畫可以修改任何物件的屬性值,屬性值可在指定的一段時間內自動改變,根據物件屬性值的變化進而實現更復雜的動畫。 1. 屬性動畫的常用設定 2. Va

js學習總結----動畫在指定時間實現單方向勻速運動

mar eight 思想 offset line ack css += hang 具體代碼如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"&g

Android筆記----動畫屬性動畫

好記性不如爛筆頭。 幀動畫 補間動畫:Alpha、Scale、Translation、Rotate 屬性動畫: 屬性動畫常用的幾個類: ObjectAnimator:物件動畫執行類 ValueAnimator:值動畫執行類 PropertyValuesHo

Android中的動畫(幀動畫、補間動畫屬性動畫

總的來說,安卓動畫可以分為兩類,最初的傳統動畫和Android3.0之後的屬性動畫。 傳統動畫包括:幀動畫( Frame Animation)和補間動畫(Tweened Animation)。 下面來具體說一下各種動畫的使用及特點: 幀動畫:是最容易實

Android開發中屬性動畫(ObjectAnimator)的應用

昨天看到一個有意思的動畫,就想用Android 中的屬性動畫(ObjectAnimator)給實現出來,順便複習一下屬性動畫的使用,完成效果如下: 看完了效果,現在該開始動手幹活了~ 首先先分析一下這個動畫用Android 中的屬性動畫該怎麼實現: 看上去這個動畫很簡單,可以用

Android開發——View動畫、幀動畫屬性動畫詳解

0. 前言Android動畫是面試的時候經常被問到的話題。我們都知道Android動畫分為三類:View動畫、幀動畫和屬性動畫。先對這三種動畫做一個概述:View動畫是一種漸進式動畫,定義動畫開始和結束

Android 屬性動畫屬性動畫 總結&攻略

轉載:http://blog.csdn.net/carson_ho/article/details/72909894 更多內容請參考: 1. 屬性動畫1:基礎知識和ValueAnimator:http://blog.csdn.net/wangxiaocheng16

Android 中關於屬性動畫的一些思考,或許能為你解決一定的效能問題

——學之開源,用於開源;初學者的心態,與君共勉!======================================================== 序 用動畫用的久了漸漸的喜歡上她了,雖然它或許並不是女的,但我希望是~~ 用的久了,我漸漸的思考效能的問題

Android為ViewPager增加切換動畫——使用屬性動畫

 ViewPager作為Android最常用的的元件之一,相信大家在專案中會頻繁的使用到的,例如利用ViewPager製作引導頁、輪播圖,甚至做整個app的表現層的框架等等。 Android3.0以下不支援切換動畫 但是在Android 3.0(API 11)以下的Vi