Android-動畫學習
1、動畫分類
- 傳統動畫(幀動畫、補間動畫)
- 3.0后的屬性動畫
2、動畫-傳統動畫
2.1、幀動畫
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/gif1" android:duration="100"/>
<item android:drawable="@mipmap/gif2" android:duration="100"/>
<item android:drawable="@mipmap/gif3" android:duration="100"/>
<item android:drawable="@mipmap/gif4" android:duration="100"/>
</animation-list>
2.2、補間動畫
①alpha(淡入淡出)
②translate(位移)
③rotate(旋轉)
④scale(放大縮小)
實例:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0.8"
android:toAlpha="0" />
<rotate
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
<scale
android:fromXScale="0"
android:fromYScale="0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1"
android:toYScale="1" />
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="1"
android:toYDelta="1" />
</set>
3、屬性動畫
3.1、出現的原因
傳統動畫的缺點: a)作用對象只是View(如只想操作視圖的顏色屬性)
b)沒有改變View的屬性,只是改變了視覺效果
c)動畫效果過于單一
3.2、特點
- 作用對象為任意java對象
- 動畫效果不只是4種變換
3.3、工作原理
屬性動畫有兩個非常重要的類:ValueAnimator、ObjectAnimator
他們的關系如圖:
相關類:
類名 | 用途 |
ValueAnimator | 屬性動畫主要的計時器,也計算動畫后的屬性的值,動畫的執行類 |
ObjectAnimator | ValueAnimator的一個子類,允許你設置一個目標對象和對象的屬性進行動畫,動畫的執行類 |
AnimatorSet | 提供組織動畫的結構,使它們能相關聯得運行,用于控制一組動畫的執行 |
AnimatorInflater | 用戶加載屬性動畫的xml文件 |
Evaluators | 屬性動畫計算器,告訴了屬性動畫系統如何計算給出屬性的值 |
Interpolators | 動畫插入器,定義動畫的變化率 |
3.4、用法
3.4.1、ValueAnimator
①原理:屬性動畫的機制是通過不斷對值進行操作實現的,而初始值和結束值之間的動畫過度就是由ValueAnimator這個類負責計算的,它的內部是使用時間循環的機制。ValueAnimator還負責管理動畫的播放次數、播放模式、以及對動畫設置監聽器等
②方法
ValueAnimator.ofInt() 初始值從整數過度到結束值
ValueAnimator.ofFloat() 初始值從浮點數過度到結束值
ValueAnimator.ofObject() 初始值從對象形式過度到結束值
③實例
一個View 4秒從原先寬度變到200的一個動畫
a)代碼方式
ValueAnimator valueAnimator = ValueAnimator.ofInt(view.getLayoutParams().width, 200);
valueAnimator.setDuration(4000);
valueAnimator.setStartDelay(500);
// 設置動畫延遲播放時間
valueAnimator.setRepeatCount(0);
// 設置動畫重復播放次數 = 重放次數+1
valueAnimator.setRepeatMode(ValueAnimator.RESTART);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int currentValue= (Integer) valueAnimator.getAnimatedValue();
view.getLayoutParams().width=currentValue;
view.requestLayout();
}
});
valueAnimator.start();
b)xml方式
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="4000"
android:repeatCount="0"
android:repeatMode="restart"
android:valueFrom="0"
android:valueTo="200"
android:valueType="intType"></animator>
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.set_animation);
// 載入XML動畫
animator.setTarget(view);
// 設置動畫對象
animator.start();
// 啟動動畫
④特殊ValueAnimator.ofObject()
1、估值器(TypeEvaluator)
插值器(Interpolator
)決定值的變化模式(勻速、加速)
估值器(TypeEvaluator
)決定值的具體變化數值
2、ValueAnimator.ofFloat()原理
其實是系統內置了一個 FloatEvaluator
估值器,內部實現了初始值與結束值 以浮點型的過渡邏輯
public class FloatEvaluator implements TypeEvaluator {
/**
* 重寫evaluate
* @param fraction 表示動畫完成度(根據它來計算當前動畫的值)
* @param startValue 動畫的初始值
* @param endValue 動畫的結束值
* @return
*/
public Object evaluate(float fraction, Object startValue, Object endValue) {
float startFloat = ((Number) startValue).floatValue();
return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
// 初始值 過渡 到結束值 的算法是:
// 1. 用結束值減去初始值,算出它們之間的差值
// 2. 用上述差值乘以fraction系數
// 3. 再加上初始值,就得到當前動畫的值
}
}
3、ValueAnimator.ofObject() 從一個點到另一個點移動實例
public class Point {
private float x;
private float y;
public Point(float x, float y) {
this.x = x;
this.y = y;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
}
public class PointEvaluator implements TypeEvaluator {
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
// 將動畫初始值startValue 和 動畫結束值endValue 強制類型轉換成Point對象
Point startPoint = (Point) startValue;
Point endPoint = (Point) endValue;
float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());
float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY());
// 將計算后的坐標封裝到一個新的Point對象中并返回
Point point = new Point(x, y);
return point;
}
}
public class MyView extends View {
// 設置需要用到的變量
public static final float RADIUS = 70f;// 圓的半徑 = 70
private Point currentPoint;// 當前點坐標
private Paint mPaint;// 繪圖畫筆
// 構造方法(初始化畫筆)
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// 初始化畫筆
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.BLUE);
}
// 復寫onDraw()從而實現繪制邏輯
// 繪制邏輯:先在初始點畫圓,通過監聽當前坐標值(currentPoint)的變化,每次變化都調用onDraw()重新繪制圓,從而實現圓的平移動畫效果
@Override
protected void onDraw(Canvas canvas) {
// 如果當前點坐標為空(即第一次)
if (currentPoint == null) {
currentPoint = new Point(RADIUS, RADIUS);
// 創建一個點對象(坐標是(70,70))
// 在該點畫一個圓:圓心 = (70,70),半徑 = 70
float x = currentPoint.getX();
float y = currentPoint.getY();
canvas.drawCircle(x, y, RADIUS, mPaint);
// 步驟1:創建初始動畫時的對象點 & 結束動畫時的對象點
Point startPoint = new Point(RADIUS, RADIUS);// 初始點為圓心(70,70)
Point endPoint = new Point(700, 1000);// 結束點為(700,1000)
// 步驟2:創建動畫對象 & 設置初始值 和 結束值
ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
// 步驟3:設置動畫參數
anim.setDuration(5000);
// 設置動畫時長
// 步驟3:通過 值 的更新監聽器,將改變的對象手動賦值給當前對象
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentPoint = (Point) animation.getAnimatedValue();
// 將每次變化后的坐標值(估值器PointEvaluator中evaluate()返回的Piont對象值)到當前坐標值對象(currentPoint)
// 從而更新當前坐標值(currentPoint)
// 步驟4:每次賦值后就重新繪制,從而實現動畫效果
invalidate();
// 調用invalidate()后,就會刷新View,即才能看到重新繪制的界面,即onDraw()會被重新調用一次
// 所以坐標值每改變一次,就會調用onDraw()一次
}
});
anim.start();
// 啟動動畫
} else {
// 在該點畫一個圓:圓心 = (30,30),半徑 = 30
float x = currentPoint.getX();
float y = currentPoint.getY();
canvas.drawCircle(x, y, RADIUS, mPaint);
}
}
}
3.4.2、ObjectAnimator
① ValueAnimator與ObjectAnimator區別
ValueAnimator
類是先改變值,然后 手動賦值 給對象的屬性從而實現動畫;是 間接對對象屬性進行操作;ObjectAnimator
類是先改變值,然后 自動賦值 給對象的屬性從而實現動畫;是 直接對對象屬性進行操作;
② 使用方法
a)代碼方式
ObjectAnimator anim = ObjectAnimator.ofFloat(object, property, values);
anim.setDuration(500);// 設置動畫運行的時長
anim.setStartDelay(500);// 設置動畫延遲播放時間
anim.setRepeatCount(0);// 設置動畫重復播放次數 = 重放次數+1
anim.setRepeatMode(ValueAnimator.RESTART);// 設置重復播放動畫模式
anim.start();// 啟動動畫
b)xml方式
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType"
android:propertyName="alpha">
</objectAnimator>
③ 實現補間動畫四種基本變化(平移、旋轉、縮放 、透明度)
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(view, "alpha", 0.8f, 0f);//逐漸透明
ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(view, "scaleX", 1f, 3f);//X軸方向縮放到3倍
ObjectAnimator translateAnim = ObjectAnimator.ofFloat(view, "translationX", view.getTranslationX(), 200,view.getTranslationX());//X軸平移
ObjectAnimator rotateAnim = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f);//360度旋轉
智能推薦
Android動畫學習總結(一)
Android動畫主要有三種:view動畫,幀動畫,屬性動畫。 1.view動畫:也叫補間動畫,通過對場景的對象不斷做圖像變換(平移,縮放,旋轉,透明度)從而產生動畫效果,是一種漸進式動畫。 四種動畫效果對應四種子類: 動畫效果 標簽 java類 平移動畫 <translate> TranslateAnimation 縮放動畫 <scale...
Android轉場動畫的學習
本文轉自:http://www.jianshu.com/p/e63090e06c3e# 最近在UI中國看見一個很好看的效果,它是這樣的: yuansu2.gif 鏈接地址:http://www.ui.cn/detail/237678.html 然后我上網搜了一下,發現Android5.0以上版本,在Activity切換時是有提供動畫的。 所以這篇文章會簡單的介紹一下Android的幾種轉場動畫,才...
Android動畫學習總結(三)
3.屬性動畫:3.0之前只有view動畫和幀動畫,這兩種動畫只改變view的視覺效果,對其屬性無影響。所以加入了屬性動畫。 在動畫持續時間內,通過不斷對值進行改變,并不斷將該值賦給對象,從而實現該對象在任意屬性上的動畫效果。 利用屬性動畫組合實現view動畫的四種操作。 動畫效果: ...
Android動畫學習總結(二)
2.幀動畫:順序播放一組預先設定好的圖片,類似與電影的播放。系統提供AnimationDrawable類來使用幀動畫 先創建幀動畫的xml布局,路徑為res/drawable/anim_frame_test 設置動畫 動畫效果: 至此就實現了幀動畫的完整過程...
Android學習——Animation動畫效果
1.Android動畫模式: 1>tweened animation: 漸變動畫; 2>frame by frame: 畫面轉換動畫. 2.Android的Animation動畫由四種類型組成: XML alpha 漸變透明度動畫效果 scale 漸變尺寸伸縮動畫效果 translate 畫面轉換位置移動動畫效果 rotate 畫...
猜你喜歡
Android學習筆記(Android Studio)屬性動畫
Android學習筆記 屬性動畫 推薦新手向學習視頻:B站https://www.bilibili.com/video/av38409964點我傳送 屬性動畫 屬性動畫在移動結束后,可以點擊移動后的位置,因為其屬性改變了。但是補間動畫,點擊移動后的位置無效,點擊原來的地方才有效,因為屬性沒改變。 ValueAnimator ObjectAnimator.ofFloat() 動畫類型供參考: tra...
Android 學習筆記-動畫 畫布的學習
畫布的學習 首先創建一個類繼承自View就可以了 這是畫矩形的; 主類里直接幀布局layout添加即可 動畫 創建一個anmi文件夾,然后在創建一個anml.xml alpha是淡入淡出標記 主類啟動一下就完事...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...