安卓系統的預設屬性
安卓系統中提供了一系列的屬性動畫供你使用,常用的包括:
屬性名稱 | 描述 |
---|---|
X | 在父容器(非螢幕)的距離左側的距離,即X軸的距離 |
Y | 在父容器(非螢幕)的距離頂部的距離,即Y軸的距離 |
scaleX | X軸方向的縮放,Y軸大小不變,從中間向兩側或者從兩側向中間 |
scaleY | Y軸方向的縮放,X軸的大小不變,從中間向兩側或者從兩側向中間 |
alpha | 透明度,為0時全透明,1時不透明 |
但是系統提供的屬性具有一定的侷限性,它只能按照系統設定好的軌跡運動,比如要改變一個影像的大小的時候,預設的是這個樣子的:
1.X軸方向縮放
2.Y軸方向縮放
可以看到,在縮放的時候是一種從中間向兩邊擴充套件的趨勢,此時比如我想要一種類似於幕布下拉的趨勢出現,它就不能完成我的要求了。
瞭解自定義屬性
上一篇文章中簡單介紹了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()複製程式碼
效果如下:
同樣的方式適用於width改變,效果如下:
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()
方法,圖片就會隨著我們指定的路徑一路運動下去,有了這個功能,屬性動畫更加強大了。
最後附上github地址
Demo