안드로이드 애니메이션 속성 애니메이션(Property Animation)

11595 단어
앞에서 설명한 트윈 애니메이션은 그 역할을 하는 View의 모양만 바꾸지만 객체 자체는 바꾸지 않았다. 속성 애니메이션 프레임은 실제 속성 값을 조작하고 대상의 속성을 직접 바꾸기 때문에 이전의 4가지 애니메이션 효과에 국한되지 않고 다양한 효과를 유연하게 실현할 수 있다.
1.ObjectAnimator  
java
    public void rotateyAnimRun(View view)  
    {  
         ObjectAnimator
         .ofFloat(view, "rotationX", 0.0F, 360.0F)  
         .setDuration(500)  
         .start();  
    } 

1. ofInt, ofFloat, ofObject를 제공했다. 이 몇 가지 방법은 애니메이션 작용의 요소, 작용의 속성, 애니메이션의 시작, 끝, 그리고 중간의 임의의 속성 값을 설정하는 것이다.
속성 값에 대해 하나만 설정할 때, 당연히 대상은 이 속성의 값이 시작 (getPropName 반사 획득) 이라고 생각하고, 설정한 값은 끝점이다.두 개를 설정하면 하나는 시작, 하나는 끝
애니메이션을 업데이트하는 과정에서 setPropName 업데이트 요소의 속성을 계속 호출합니다. ObjectAnimator를 사용하여 어떤 속성을 업데이트하려면 Getter (속성 값을 설정할 때) 와 setter 방법이 있어야 합니다.
2. 조종 가능한 속성 매개 변수: x/y;scaleX/scaleY;rotationX/rotationY;transitionX/transitionY 등등
1). translationX와translationY: 이 두 속성은 보기 대상이 용기의 왼쪽 상단 좌표에서 시작하는 위치를 증가하는 양으로 제어합니다.2). rotation, rotationX 및 rotationY: 이 세 가지 속성은 View 객체가 브랜치 주위의 2D 및 3D 회전을 제어합니다.3). scaleX와 scaleY: 이 두 속성은 View 대상이 지점을 둘러싸고 2D로 축소되는 것을 제어합니다.4). pivotX와 pivotY: 이 두 속성은View 대상의 지점 위치를 제어하고 이 지점을 둘러싸고 회전과 축소 변환 처리를 합니다.기본적으로 이 브랜치의 위치는 View 객체의 중심점입니다.5). x와 y: 이것은 두 가지 간단하고 실용적인 속성입니다. 이것은 View 대상이 용기에 있는 최종 위치를 설명합니다. 이것은 최초의 왼쪽 상단 좌표와translationX와translationY 값의 누적과입니다.6). 알파: View 객체의 알파 투명도를 나타냅니다.기본값은 1(불투명), 0은 전체 투명(보이지 않음)을 나타냅니다.
3. 위의 예를 보았는데 설정된 작업의 속성이 하나밖에 없기 때문에 만약에 애니메이션이 View를 축소할 수도 있고 꺼질 수도 있길 원한다면 (3개의 속성 scaleX, scaleY,alpha) Object Animator만 사용하면 어떻게 합니까?
아이디어가 괜찮지 않나요? Animator Set을 사용한다고 할 수도 있어요. 이거 보니까 애니메이션 마개 한 무더기가 같이 실행되는 거예요. 그런데 하필이면 Object Animator 실례로 실현해야 돼요. 다음은 코드를 볼게요.
public void rotateyAnimRun(final View view)  
{  
    ObjectAnimator anim = ObjectAnimator  
            .ofFloat(view, "huaxun", 1.0F,  0.0F)  
            .setDuration(500);  
    anim.start();  
    anim.addUpdateListener(new AnimatorUpdateListener()  
    {  
        @Override  
        public void onAnimationUpdate(ValueAnimator animation)  
        {  
            float cVal = (Float) animation.getAnimatedValue();  
            view.setAlpha(cVal);  
            view.setScaleX(cVal);  
            view.setScaleY(cVal);  
        }  
    });  
} 

속성을 설정한 문자열을 대상에 없는 속성을 아무렇게나 쓰면 됩니다. 시간 삽입값과 지속시간에 따라 계산된 값만 직접 호출하면 됩니다.
4. 사실 더 간단한 방법으로 애니메이션의 여러 가지 효과를 변경할 수 있다. 이것은propertyValuesHolder를 사용한다.
public void propertyValuesHolder(View view)  
    {  
        PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,  0f, 1f);  
        PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f);  
        PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f);  
        ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY,pvhZ).setDuration(1000).start();  
    }

xml
우선res에서animator 폴더(Tween 애니메이션과 다른Anim 폴더)를 만들고res/animator/scalex를 만듭니다.xml
<?xml version="1.0" encoding="utf-8"?>  
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"  
    android:duration="1000"  
    android:propertyName="scaleX"  
    android:valueFrom="1.0"  
    android:valueTo="2.0"  
    android:valueType="floatType" >  
</objectAnimator> 

AnimatorInflater를 사용하여 애니메이션의 자원 파일을 불러오고 대상을 설정하면 ok
public void scaleX(View view)  
    {  
        //    
        Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);  
        anim.setTarget(mMv);  
        anim.start();  
    } 

2.ValueAnimator 
ValueAnimator와 ObjectAnimator의 차이점: ValueAnimator는 속성에서 조작하지 않았습니다. 수동으로 설정해야 합니다.
장점: 조작이 필요 없는 대상의 속성은 반드시 Getter와setter 방법이 있어야 합니다. 당신은 현재 애니메이션의 계산 값에 따라 모든 속성을 조작할 수 있습니다.
1. 우리는 자유롭게 낙하하는 코드를 보았다
 public void verticalRun(View view)  
    {  
        ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight - mBlueBall.getHeight());  
        animator.setTarget(mBlueBall);
        animator.setInterpolator(new BounceInterpolator());  
        animator.setDuration(1000).start();   
        animator.addUpdateListener(new AnimatorUpdateListener()  
        {  
            @Override  
            public void onAnimationUpdate(ValueAnimator animation)  
            {  
                mBlueBall.setTranslationY((Float) animation.getAnimatedValue());  
            }  
        });  
    }  

2. 다시 한 번 예를 들어 만약에 소구 포물선 운동[포물선의 효과를 실현하고 수평방향 100px/s, 수직방향 가속도 200px/s*s]을 원한다면 분석해 보면 시간과 관계가 있는 것 같지만 시간의 변화에 따라 가로와 세로의 이동 속도가 다르다. 우리는 어떻게 실현해야 합니까?TypeValue를 다시 쓸 때가 되었습니다. 시간이 변하는 동시에 대상에게 두 개의 값, x 현재 위치, y 현재 위치로 돌아가야 하기 때문입니다.
public void paowuxian(View view)  
    {  
        ValueAnimator valueAnimator = new ValueAnimator();  
        valueAnimator.setDuration(3000);  
        valueAnimator.setObjectValues(new PointF(0, 0));  
        valueAnimator.setInterpolator(new LinearInterpolator());  
        valueAnimator.setEvaluator(new TypeEvaluator<PointF>()  
        {  
            @Override  
            public PointF evaluate(float fraction, PointF startValue,  
                    PointF endValue)  
            {   
                // x 200px/s , y 0.5 * 10 * t  
                PointF point = new PointF();  
                point.x = 200 * fraction * 3;  
                point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);  
                return point;  
            }  
        });   
        valueAnimator.start();  
        valueAnimator.addUpdateListener(new AnimatorUpdateListener()  
        {  
            @Override  
            public void onAnimationUpdate(ValueAnimator animation)  
            {  
                PointF point = (PointF) animation.getAnimatedValue();  
                mBlueBall.setX(point.x);  
                mBlueBall.setY(point.y);  
            }  
        });  
    }

보시다시피 ofInt, ofFloat 등은 사용할 수 없기 때문에 ofObject만 사용할 수 있습니다. 우리는 TypeValue를 사용자 정의하여 매번 현재 시간에 따라 PointF 대상을 되돌려줍니다. (PointF와 Point의 차이는 x입니다. y의 단위는 하나는float이고 하나는 int입니다. RectF, Rect도 마찬가지) PointF에는 x, y의 현재 위치가 포함되어 있습니다. 그리고 우리는 감청기에서 동적 속성 설정을 합니다.
3. 하나의 애니메이션으로 여러 효과 변경:propertyValuesHolder 사용
private void startTransform(final int state) {
        ValueAnimator valueAnimator = new ValueAnimator();
        valueAnimator.setDuration(300);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        PropertyValuesHolder scaleHolder = PropertyValuesHolder.ofFloat("scale", mTransfrom.startScale, mTransfrom.endScale);
        PropertyValuesHolder leftHolder = PropertyValuesHolder.ofFloat("left", mTransfrom.startRect.left, mTransfrom.endRect.left);
        PropertyValuesHolder alphaHolder = PropertyValuesHolder.ofInt("alpha", 0, 255);
        valueAnimator.setValues(scaleHolder, leftHolder, alphaHolder);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public synchronized void onAnimationUpdate(ValueAnimator animation) {
                mTransfrom.scale = (Float) animation.getAnimatedValue("scale");
                mTransfrom.rect.left = (Float) animation.getAnimatedValue("left");
                mBgAlpha = (Integer) animation.getAnimatedValue("alpha");
                invalidate();
                ((Activity)getContext()).getWindow().getDecorView().invalidate();
            }
        });
4.애니메이션에 대한 스니퍼 이벤트
public void fadeOut(View view)  
    {  
        ObjectAnimator anim = ObjectAnimator.ofFloat(mBlueBall, "alpha", 0.5f);       
        anim.addListener(new AnimatorListener()  
        {  
            @Override  
            public void onAnimationStart(Animator animation)  {}
            @Override  
            public void onAnimationRepeat(Animator animation)  {}
            @Override  
            public void onAnimationEnd(Animator animation)  {}
            @Override  
            public void onAnimationCancel(Animator animation)  {}
        });  
        anim.start();  
    }  

이렇게 하면 애니메이션의 시작, 끝, 취소, 중복 등 사건을 감청할 수 있다. 그러나 때때로 나는 끝만 알면 된다고 생각할 때가 있다. 이렇게 긴 코드를 나는 받아들일 수 없다. 그러면 너는 Animator Listener Adapter를 사용할 수 있다. Animator Listener Adapter는 Animator Listener 인터페이스를 계승하고 모든 방법을 헛되이 실현할 수 있다.
anim.addListener(new AnimatorListenerAdapter()  
{  
    @Override  
    public void onAnimationEnd(Animator animation)  {}  
});

5.
AnimatorSet 사용
java
  public void togetherRun(View view)  
    {  
        ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX", 1.0f, 2f);  
        ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY", 1.0f, 2f);  
        AnimatorSet animSet = new AnimatorSet();  
        animSet.setDuration(2000);  
        animSet.setInterpolator(new LinearInterpolator());  
        //   
        animSet.playTogether(anim1, anim2);  
        animSet.start();  
    } 
public void playWithAfter(View view)  
    {  
        float cx = mBlueBall.getX(); 
        ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX", 1.0f, 2f);  
        ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY", 1.0f, 2f);  
        ObjectAnimator anim3 = ObjectAnimator.ofFloat(mBlueBall, "x",  cx ,  0f);  
        ObjectAnimator anim4 = ObjectAnimator.ofFloat(mBlueBall, "x", cx);     
        /** 
         * anim1,anim2,anim3  
         * anim4  
         */  
        AnimatorSet animSet = new AnimatorSet();  
        animSet.play(anim1).with(anim2);  
        animSet.play(anim2).with(anim3);  
        animSet.play(anim4).after(anim3);  
        animSet.setDuration(1000);  
        animSet.start();  
    }  

두 가지 효과가 적혀 있습니다.
첫 번째:플레이 투게더 두 애니메이션을 동시에 실행하고 플레이 Sequentially도 순서대로 실행합니다~~
둘째, 만약에 우리가 애니메이션을 한 무더기 가지고 있다면 코드 제어 순서를 어떻게 사용하는가. 예를 들어 1, 2와 동시에.3 은 2 뒤에 있다.4. 1 하기 전에 기다리면 2예요.
주의 사항: animSet.play().with();체인 프로그래밍도 지원하지만, 예를 들면 animSet을 생각하지 마세요.play(anim1).with(anim2).before(anim3).before(anim5); 이렇게 해서는 안 된다. 시스템은 네가 쓴 이 긴 줄에 근거하여 선후의 순서를 결정하지 않을 것이다
xml
<?xml version="1.0" encoding="utf-8"?>  
<set xmlns:android="http://schemas.android.com/apk/res/android"  
    android:ordering="together" >  
    <objectAnimator  
        android:duration="1000"  
        android:propertyName="scaleX"  
        android:valueFrom="1"  
        android:valueTo="0.5" >  
    </objectAnimator>  
    <objectAnimator  
        android:duration="1000"  
        android:propertyName="scaleY"  
        android:valueFrom="1"  
        android:valueTo="0.5" >  
    </objectAnimator>  
</set> 

set 탭을 사용하면,orderring 속성이 together로 설정되어 있고, 또 다른 값이 있습니다:sequentially (하나하나 실행됨을 표시합니다)
//    
        Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);  
        mMv.setPivotX(0);  
        mMv.setPivotY(0);  
        // invalidate  
        mMv.invalidate();  
        anim.setTarget(mMv);  
        anim.start(); 

좋은 웹페이지 즐겨찾기