---
# System prepended metadata

title: View animation
tags: [Android, 基礎, Java]

---

# View animation

###### tags:  `Android` `Java` `基礎`
###### 2018/10/16


- 要放在支援檔
- 支援檔統一放在 res/anim/ 裡面
- 只針對繪製的那一段做改動，屬性都不會被改動，包括它的位置

#### android:fillAfter

- 預設是"false" ->動畫結束後會彈回去
- "true" ->動畫結束是畫面停留在最後一幀


alpha
scale
translate
rotate
set => 動畫集合


#### 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) {

}