programing

안드로이드에서 이미지 회전을 원활하게 하는 방법은 무엇입니까?

closeapi 2023. 8. 9. 20:45
반응형

안드로이드에서 이미지 회전을 원활하게 하는 방법은 무엇입니까?

사용 중입니다.RotateAnimationAndroid에서 사용자 지정 순환 스피너로 사용하는 이미지를 회전합니다.제 여기내입니다.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" />    

을 저의 이을나것적용때할에의것▁my에 때.ImageView용사를 AndroidUtils.loadAnimation()잘 작동합니다!

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

한 가지 문제는 이미지 회전이 매 사이클의 맨 위에서 일시 중지되는 것처럼 보인다는 것입니다.

즉, 이미지가 360도 회전하고 잠시 멈춘 다음 다시 360도 회전하는 등의 작업을 수행합니다.

를 사용하는 것이 문제인 것 같습니다.android:iterpolator="@android:anim/accelerate_interpolator"(AccelerateInterpolator 말해야 모르겠습니다.), 하만애니말지어라고말떻할해모다지니습르겠야지게간보하을션이메▁),.

애니메이션 주기를 원활하게 만들기 위해 보간 기능(문제가 있는 경우)을 해제하려면 어떻게 해야 합니까?

Accelerate에 대한 귀하의 말씀이 옳습니다.보간기. 선형을 사용해야 합니다.대신 인터폴레이터.

기본 제공 기능을 사용할 수 있습니다.android.R.anim.linear_interpolator 파일을 사용할 수 있습니다.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°가 같기 때문입니다.

ObjectAnimator.ofFloat(view, View.ROTATION, 0f, 360f).setDuration(300).start();

이거 먹어봐요.

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

시계 방향으로 회전:

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

반시계방향 회전:

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

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

rotate.repeatCount(10)를 설정합니다. 회전을 반복할 때 사용합니다.

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

가지치기<set>- 시스템을 감싸는 요소<rotate>-요소가 문제를 해결합니다!

샬라피 덕분입니다!

따라서 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"
    />

코틀린에서:

 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)
        })

Ashanry가 위에서 언급한 바와 같이 라이너 인터폴레이터를 장착하는 것은 괜찮습니다.그러나 회전이 세트 안에 있으면 부드럽게 하려면 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>

공유 인터폴레이터가 거짓이 아닌 경우 위의 코드는 결함을 제공합니다.

만약 당신이 나와 같은 세트 애니메이션을 사용하고 있다면, 당신은 세트 태그 안에 보간을 추가해야 합니다.

<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>

그건 나한테 효과가 있었어요.

아무리 노력해도 원활한 회전 애니메이션을 위해 코드(및 회전 설정)를 사용하여 이 작업을 제대로 수행할 수 없었습니다.결국 제가 한 일은 정도의 변화를 아주 작게 만들어서 작은 멈춤이 눈에 띄지 않게 만드는 것이었습니다.너무 많은 회전을 수행할 필요가 없는 경우 이 루프를 실행하는 데 걸리는 시간은 무시해도 됩니다.이 효과는 매끄러운 회전입니다.

        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);
        }

다시 시작하지 않으려면 360 이상을 사용합니다.

저는 360 대신 3600을 사용하는데 이것은 저에게 잘 작동합니다.

<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%" />

다음은 제게 잘 작동한 코드 조각입니다.

    RotateAnimation rotate = new RotateAnimation(
            0, 359,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f
    );

    rotate.setDuration(1500);
    rotate.setRepeatCount(Animation.INFINITE);
    yourView.startAnimation(rotate);

360이 아닌 것을 확인하세요. 0과 360이 같은 지점에 있기 때문에 생성자에서 359입니다.

0에서 360으로 이동하기 때문에 예상보다 0/360에서 조금 더 많은 시간을 보낼 수 있습니까?아마도 섭씨 359도 또는 358도로 설정됩니다.

private fun rotateTheView(view: View?, startAngle: Float, endAngle: Float) {
    val rotate = ObjectAnimator.ofFloat(view, "rotation", startAngle, endAngle)
    //rotate.setRepeatCount(10);
    rotate.duration = 400
    rotate.start()
}

다음 코드를 사용할 수 있습니다.

view.animate().rotation(360.0f).setDuration(1000);

100% 정답

    var rotate = RotateAnimation(
            0F, 360F,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f
    )

  rotate.duration = 999
        rotate.repeatCount = Animation.INFINITE

   imageview..setAnimation(rotate)

100% 작동!!!

Android에서 객체를 애니메이션화하여 위치 1에서 위치 2로 객체를 이동시키려면 애니메이션 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));
    }
}

언급URL : https://stackoverflow.com/questions/1634252/how-to-make-a-smooth-image-rotation-in-android

반응형