# Animation
###### tags: `Android` `Java` `基礎`
###### 2018/10/16
Android中的Animation分為三種:
- Drawable Animation: 逐幀動畫,用在比較簡單的動畫
- View Animation: 只針對繪製的那一段做改動,屬性都不會被改動,包括它的位置
- Property Animation: 直接改變它的屬性,3.0 以後才支援
| Drawable Animation |View Animation | Property Animation|
| -------- | -------- | -------- |
| [ref](https://developer.android.com/guide/topics/graphics/drawable-animation) | Text | Text |
## Drawable Animation
## View animation
- 要放在支援檔
- 支援檔統一放在 anim 的 directory
#### android:fillAfter
- 預設是"false" ->動畫結束後會彈回去
- "true" ->動畫結束是畫面停留在最後一幀
#### translation
用於控制view的位移
android:fromXDelta => 起始X坐標(偏移)
android:toXDelta => 結束坐標(偏移)
android:fromYDelta => 起始Y坐標(偏移)
android:toYDelta => 結束Y坐標(偏移)
以上屬性有三種格式
- (50%) (50%p) (50)•% => 自身高/寬
- 100%~100%的位置•%p => 父元件高/寬
- 100%~100%的位置•數字 => px
``` xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0%" <--! 0 -> -->
android:fromYDelta="0"
android:toXDelta="30%p"
android:toYDelta="30%p"
android:duration="2000"
android:fillAfter="true"
>
</translate>
```
是LayoutInflater是用來找res/layout/下的xml佈局文件,並且實例化;作用類似於findViewById(),
而findViewById()是找xml佈局文件下的具體widget控件(如 Button、TextView等)
```
public class CLL extends LinearLayout {
public CLL(Context context) {
super(context);
init(context);
}
public CLL(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CLL(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public CLL(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private int tmpHeight;
private boolean isCollapse;
private Context context;
private void init(Context context){
tmpHeight = 0;
isCollapse = false;
this.context = context;
}
public void change(){
if(getMeasuredHeight() > tmpHeight)
tmpHeight = getMeasuredHeight();// 這個LinearLayout最大的高度 if(isCollapse){
expand();
}else{
collapse();
}
isCollapse = !isCollapse;
}
private void expand(){
ValueAnimator animator =
(ValueAnimator)AnimatorInflater.loadAnimator(context, R.animator.anim1);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
int currentValue = (int)animation.getAnimatedValue();
getLayoutParams().height = (int)(tmpHeight * ((120 - currentValue)/100f));
requestLayout();
if(currentValue == 20 && changedListener != null){
changedListener.expand();
}
}
});
animator.start();
}
private void collapse(){
ValueAnimator animator =
(ValueAnimator)AnimatorInflater.loadAnimator(context, R.animator.anim1);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
int currentValue = (int)animation.getAnimatedValue();
getLayoutParams().height = (int)(tmpHeight * (currentValue/100f));
requestLayout();
if(currentValue == 20 && changedListener != null){
changedListener.collapse();
}
}
});
animator.start();
}
ChangedListener changedListener;
public void setChangedListener(ChangedListener changedListener){
this.changedListener = changedListener;
}
public interface ChangedListener{
void expand();
void collapse();
}
}
```
test(1);
test(1,2,3);
test(1,2,3,4,5,6);
public void test(int... values) {
}