安卓Property Animator動畫詳解(二)-自定義屬性

saka發表於2019-03-04

安卓系統的預設屬性

安卓系統中提供了一系列的屬性動畫供你使用,常用的包括:

屬性名稱 描述
X 在父容器(非螢幕)的距離左側的距離,即X軸的距離
Y 在父容器(非螢幕)的距離頂部的距離,即Y軸的距離
scaleX X軸方向的縮放,Y軸大小不變,從中間向兩側或者從兩側向中間
scaleY Y軸方向的縮放,X軸的大小不變,從中間向兩側或者從兩側向中間
alpha 透明度,為0時全透明,1時不透明

但是系統提供的屬性具有一定的侷限性,它只能按照系統設定好的軌跡運動,比如要改變一個影像的大小的時候,預設的是這個樣子的:
1.X軸方向縮放

安卓Property Animator動畫詳解(二)-自定義屬性

2.Y軸方向縮放

安卓Property Animator動畫詳解(二)-自定義屬性

可以看到,在縮放的時候是一種從中間向兩邊擴充套件的趨勢,此時比如我想要一種類似於幕布下拉的趨勢出現,它就不能完成我的要求了。

瞭解自定義屬性

上一篇文章中簡單介紹了animator的一些基本使用,這次介紹一下除了可以使用系統提供的預設屬性,還可以自定義屬性,在程式碼中使用。

ObjectAnimator的第一個引數允許我們傳一個Object進去,而不是具體的某個view或者viewgroup,這樣的做的目的是提高屬性動畫的適配範圍,我們可以把自己自己定義一個類,用來包裹你的view,然後通過設定這個類的一些getter和setter方法來產生你想要的動畫效果。

這個包裹類必須要有setter方法,因為Animator這個時間引擎正式通過計算值來設定view的屬性而打到動畫不斷更新的目的。而getter方法可以不設定,但是假如傳的value值只有一個,會預設把引數作為結束值,此時你必須設定setter方法,動畫系統會把setter中的值設為起始值。
通過一個簡單的例子拉使用一下:

現在我有一個圖片,我需要以幕布下拉的方式來展現一張圖片,思路是這樣的,假設從Y軸向下展示,此時我要做一個包裝類出來,傳入要動畫的view作為引數,通過設定view的寬度來不斷更新view。

public class ImageViewWrapper {

    private ImageView imageView;
    private ViewGroup.LayoutParams lp;

    public ImageViewWrapper(ImageView imageView) {
        this.imageView = imageView;
        imageView.setScaleType(ImageView.ScaleType.CENTER);
        lp = imageView.getLayoutParams();
    }

    public ImageView getImageView() {
        return imageView;
    }

    public void setImageView(ImageView imageView) {
        this.imageView = imageView;
    }
}複製程式碼

以上方法設定了一個imageview包裹器,並獲取了layoutparams,這個lp是用來設定新的佈局引數的,然後我們把layoutparams的scaletype設定為了center,這樣圖片的大小就會始終是原始大小,不會因為width或者height中的某一個值改變而按比例縮放。
下面定義我們自己的屬性設定於屬性獲取器:

public void setHeight(float height) {
        lp.height = (int) height;
        imageView.setLayoutParams(lp);
    }複製程式碼

設定imageview 的高度,要通過layoutparams來設定。這樣我們就可以在ObjectAnimator中使用我們自定義的屬性了。
此處使用的是ofFloat(Object target, String propertyName, float... values)

ImageViewWrapper i = new ImageViewWrapper(imageView);
 ObjectAnimator animator1 = ObjectAnimator.ofFloat(i, "height", 0, 100);
        animator1.setDuration(1000);
animator1.start()複製程式碼

效果如下:

安卓Property Animator動畫詳解(二)-自定義屬性

同樣的方式適用於width改變,效果如下:

安卓Property Animator動畫詳解(二)-自定義屬性

Note: propertyname這個值(也就是ObjectAnimator.ofFLoat()中的第二個引數)一定要與setter中的一樣。

API中還可以使用Property來獲取屬性名稱,
ofFloat(T target, Property<T, Float> property, float... values)

不過這個方式是利用了反射射,此處不推薦:

Property p = Property.of(ImageViewWrapper.class, Float.class, "width");
        ObjectAnimator animator = ObjectAnimator.ofFloat(i, p, 0, 100);複製程式碼

效果與上邊一樣的。

此處有一個方法要介紹一下

ofInt (Object target, 
                String xPropertyName, 
                String yPropertyName, 
                Path path)複製程式碼

在這個方法中可以傳入路徑作為引數,讓物體按我們自己想要的路徑來運動。

Path path=new Path();
        path.addCircle(200,200,100, Path.Direction.CW);
        ObjectAnimator animator4=ObjectAnimator.ofFloat(imageView,"X","Y",path);
        animator.setDuration(5000);複製程式碼

這裡設定一個簡單的圓形路徑,然後呼叫
animator4.start()
方法,圖片就會隨著我們指定的路徑一路運動下去,有了這個功能,屬性動畫更加強大了。

安卓Property Animator動畫詳解(二)-自定義屬性

最後附上github地址
Demo

相關文章