문제

나는 a를 사용하고있다 RotateAnimation 안드로이드에서 사용자 정의 순환 스피너로 사용하는 이미지를 회전하려면 여기 내 rotate_indefinitely.xml 내가 배치 한 파일 res/anim/:

<?xml version="1.0" encoding="UTF-8"?>
<rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:duration="1200" />    

내가 이것을 내에게 적용 할 때 ImageView 사용 AndroidUtils.loadAnimation(), 그것은 훌륭하게 작동합니다!

spinner.startAnimation( 
    AnimationUtils.loadAnimation(activity, R.anim.rotate_indefinitely) );

한 가지 문제는 이미지 회전이 모든 사이클의 상단에서 일시 중지되는 것 같습니다.

다시 말해, 이미지는 360도 회전하고 잠시 일시 정지 한 다음 다시 360도 회전 등을 회전합니다.

문제는 애니메이션이 다음과 같은 기본 보간기를 사용하고 있다고 생각합니다. android:iterpolator="@android:anim/accelerate_interpolator" (AccelerateInterpolator), 그러나 나는 애니메이션을 보간하지 말라고 말하는 방법을 모른다.

애니메이션주기를 부드럽게 만들기 위해 보간 (실제로 문제라면)을 끄는 방법은 무엇입니까?

도움이 되었습니까?

해결책

당신은 가속기 전환기에 대해 옳습니다. 대신 LinearInterpolator를 사용해야합니다.

내장을 사용할 수 있습니다 android.R.anim.linear_interpolator 애니메이션 XML 파일에서 android:interpolator="@android:anim/linear_interpolator".

또는 프로젝트에서 나만의 XML 보간 파일을 만들 수 있습니다. res/anim/linear_interpolator.xml:

<?xml version="1.0" encoding="utf-8"?>
<linearInterpolator xmlns:android="http://schemas.android.com/apk/res/android" />

애니메이션 XML에 추가하십시오 :

android:interpolator="@anim/linear_interpolator"

특별 노트 : 회전 애니메이션이 세트 내부에 있으면 인터 폴자를 설정하는 것이 작동하지 않는 것 같습니다. 상단 요소를 회전 시키면 수정됩니다. (이것은 시간을 절약 할 것입니다.)

다른 팁

나는이 문제도 있었고 성공하지 않고 XML에서 선형 보간기를 설정하려고 노력했다. 저를 위해 일한 솔루션은 코드의 회전식으로 애니메이션을 만드는 것이 었습니다.

RotateAnimation rotate = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(5000);
rotate.setInterpolator(new LinearInterpolator());

ImageView image= (ImageView) findViewById(R.id.imageView);

image.startAnimation(rotate);

이것은 잘 작동합니다

<?xml version="1.0" encoding="UTF-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1600"
    android:fromDegrees="0"
    android:interpolator="@android:anim/linear_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:toDegrees="358" />

반전 회전 :

<?xml version="1.0" encoding="UTF-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1600"
    android:fromDegrees="358"
    android:interpolator="@android:anim/linear_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:toDegrees="0" />

어쩌면 이와 같은 것이 도움이 될 것입니다.

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        imageView.animate().rotationBy(360).withEndAction(this).setDuration(3000).setInterpolator(new LinearInterpolator()).start();
    }
};

imageView.animate().rotationBy(360).withEndAction(runnable).setDuration(3000).setInterpolator(new LinearInterpolator()).start();

그건 그렇고, 당신은 다음과 같이 360 이상으로 회전 할 수 있습니다.

imageView.animate().rotationBy(10000)...

사용해보십시오 toDegrees="359" 360 °와 0 °는 동일하기 때문입니다.

가지 치기 <set>-포장 한 요소 <rotate>-요소는 문제를 해결합니다!

Shalafi에게 감사합니다!

따라서 rotation_ccw.xml은 다음과 같이 루크해야합니다.

<?xml version="1.0" encoding="utf-8"?>

<rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="-360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="2000"
    android:fillAfter="false"
    android:startOffset="0"
    android:repeatCount="infinite"
    android:interpolator="@android:anim/linear_interpolator"
    />
ObjectAnimator.ofFloat(view, View.ROTATION, 0f, 360f).setDuration(300).start();

이 시도.

내가 시도한 내용에 관계없이 부드러운 회전 애니메이션을 위해 코드 (및 setRotation)를 사용하여 올바르게 작동 할 수 없었습니다. 내가 한 일은 학위 변화를 너무 작게 만드는 것이 었습니다. 작은 일시 정지는 눈에 띄지 않습니다. 너무 많은 회전을 할 필요가 없다면이 루프를 실행할 시간은 무시할 수 있습니다. 효과는 원활한 회전입니다.

        float lastDegree = 0.0f;
        float increment = 4.0f;
        long moveDuration = 10;
        for(int a = 0; a < 150; a++)
        {
            rAnim = new RotateAnimation(lastDegree, (increment * (float)a),  Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            rAnim.setDuration(moveDuration);
            rAnim.setStartOffset(moveDuration * a);
            lastDegree = (increment * (float)a);
            ((AnimationSet) animation).addAnimation(rAnim);
        }

Hanry가 위에서 언급했듯이 라이너 ITERPOLATOR는 괜찮습니다. 그러나 회전이 세트 내부에 있으면 Android : ShareInterPolator = "False"를 부드럽게하도록해야합니다.

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
**android:shareInterpolator="false"**
>
<rotate
    android:interpolator="@android:anim/linear_interpolator"
    android:duration="300"
    android:fillAfter="true"
    android:repeatCount="10"
    android:repeatMode="restart"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%" />
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:duration="3000"
    android:fillAfter="true"
    android:pivotX="50%"
    android:pivotY="50%"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:toXScale="0"
    android:toYScale="0" />
</set>

SharedInterpolator가 거짓이 아닌 경우 위의 코드는 결함을줍니다.

프로그래밍 방식으로 회전 객체.

// 시계 방향 회전 :

    public void rorate_Clockwise(View view) {
        ObjectAnimator rotate = ObjectAnimator.ofFloat(view, "rotation", 180f, 0f);
//        rotate.setRepeatCount(10);
        rotate.setDuration(500);
        rotate.start();
    }

// 반 시계 방향 회전 :

 public void rorate_AntiClockwise(View view) {
        ObjectAnimator rotate = ObjectAnimator.ofFloat(view, "rotation", 0f, 180f);
//        rotate.setRepeatCount(10);
        rotate.setDuration(500);
        rotate.start();
    } 

보다 ImageView 또는 기타 위젯의 객체입니다.

rotate.setRepeatCount (10); 회전을 반복하는 데 사용하십시오.

500 애니메이션 시간 지속 시간입니다.

나와 같은 세트 애니메이션을 사용하는 경우 세트 태그 내부에 보간을 추가해야합니다.

<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator">

 <rotate
    android:duration="5000"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:startOffset="0"
    android:toDegrees="360" />

 <alpha
    android:duration="200"
    android:fromAlpha="0.7"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:toAlpha="1.0" />

</set>

그것은 나를 위해 일했다.

0에서 360으로 가기 때문에 기대하는 것보다 0/360에서 조금 더 많은 시간을 소비 할 수 있습니까? 아마도 Todrees를 359 또는 358로 설정했습니다.

안드로이드에서 객체를 애니메이션하고 객체를 Location1에서 Location2로 이동시키려면 애니메이션 API가 중간 위치 (트윈)을 파악한 다음 타이머를 사용하여 적절한 시간에 적절한 이동 작업을 메인 스레드에 대기합니다. . 메인 스레드는 일반적으로 페인팅, 파일 열기, 사용자 입력 등에 응답하는 다른 많은 것들에 일반적으로 사용된다는 점을 제외하고는 잘 작동합니다. 대기 타이머가 종종 지연 될 수 있습니다. 잘 작성된 프로그램은 항상 백그라운드 (메인이 아닌) 스레드에서 가능한 많은 작업을 수행하려고하지만 항상 기본 스레드를 사용하지는 않습니다. UI 객체에서 작동 해야하는 작업은 항상 기본 스레드에서 수행해야합니다. 또한 많은 API는 스레드 안전 형태로 작업을 기본 스레드로 다시 퍼뜨릴 것입니다.

모든 사용자 상호 작용에도 사용되는 동일한 GUI 스레드에 뷰가 모두 그려집니다.

따라서 GUI를 신속하게 업데이트해야하거나 렌더링에 너무 많은 시간이 걸리고 사용자 경험에 영향을 미치는 경우 SurfaceView를 사용하십시오.

회전 이미지의 예 :

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    private DrawThread drawThread;

    public MySurfaceView(Context context) {
        super(context);
        getHolder().addCallback(this);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {   
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        drawThread = new DrawThread(getHolder(), getResources());
        drawThread.setRunning(true);
        drawThread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        drawThread.setRunning(false);
        while (retry) {
            try {
                drawThread.join();
                retry = false;
            } catch (InterruptedException e) {
            }
        }
    }
}


class DrawThread extends Thread{
    private boolean runFlag = false;
    private SurfaceHolder surfaceHolder;
    private Bitmap picture;
    private Matrix matrix;
    private long prevTime;

    public DrawThread(SurfaceHolder surfaceHolder, Resources resources){
        this.surfaceHolder = surfaceHolder;

        picture = BitmapFactory.decodeResource(resources, R.drawable.icon);

        matrix = new Matrix();
        matrix.postScale(3.0f, 3.0f);
        matrix.postTranslate(100.0f, 100.0f);

        prevTime = System.currentTimeMillis();
    }

    public void setRunning(boolean run) {
        runFlag = run;
    }

    @Override
    public void run() {
        Canvas canvas;
        while (runFlag) {
            long now = System.currentTimeMillis();
            long elapsedTime = now - prevTime;
            if (elapsedTime > 30){

                prevTime = now;
                matrix.preRotate(2.0f, picture.getWidth() / 2, picture.getHeight() / 2);
            }
            canvas = null;
            try {
                canvas = surfaceHolder.lockCanvas(null);
                synchronized (surfaceHolder) {
                    canvas.drawColor(Color.BLACK);
                    canvas.drawBitmap(picture, matrix, null);
                }
            } 
            finally {
                if (canvas != null) {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
        }
    }
}

활동:

public class SurfaceViewActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MySurfaceView(this));
    }
}

다시 시작하지 않으려면 360 이상을 사용해보십시오.

나는 3600을 360으로 사용하고 이것은 나에게 잘 작동합니다.

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="3600"
    android:interpolator="@android:anim/linear_interpolator"
    android:repeatCount="infinite"
    android:duration="8000"
    android:pivotX="50%"
    android:pivotY="50%" />

Kotlin에서 :

 ivBall.setOnClickListener(View.OnClickListener {

            //Animate using XML
            // val rotateAnimation = AnimationUtils.loadAnimation(activity, R.anim.rotate_indefinitely)

            //OR using Code
            val rotateAnimation = RotateAnimation(
                    0f, 359f,
                    Animation.RELATIVE_TO_SELF, 0.5f,
                    Animation.RELATIVE_TO_SELF, 0.5f

            )
            rotateAnimation.duration = 300
            rotateAnimation.repeatCount = 2

            //Either way you can add Listener like this
            rotateAnimation.setAnimationListener(object : Animation.AnimationListener {

                override fun onAnimationStart(animation: Animation?) {
                }

                override fun onAnimationRepeat(animation: Animation?) {
                }

                override fun onAnimationEnd(animation: Animation?) {

                    val rand = Random()
                    val ballHit = rand.nextInt(50) + 1
                    Toast.makeText(context, "ballHit : " + ballHit, Toast.LENGTH_SHORT).show()
                }
            })

            ivBall.startAnimation(rotateAnimation)
        })
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top