안드로이드에서 이미지를 부드럽게 회전시키는 방법은 무엇입니까?
RotateAnimation
Android에서 커스텀 주기적 스피너로 사용하는 이미지를 회전시키는 데 a 를 사용하고 있습니다. 여기 내 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
) 와 같은 기본 보간기를 사용하고 있다고 생각 하지만 애니메이션을 보간하지 말라고하는 방법을 모르겠습니다.
내 애니메이션을 부드럽게 순환시키기 위해 보간을 끄려면 어떻게해야합니까?
귀하는 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으로 만드는 것입니다.
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();
이 시도.
가지 치기 <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"
/>
프로그래밍 방식으로 회전 객체.
// 시계 방향 회전 :
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();
}
view 는 ImageView 또는 다른 위젯의 객체입니다.
rotate.setRepeatCount (10); 회전을 반복하는 데 사용합니다.
애니메이션 시간은 500 입니다.
내가 시도한 것에 관계없이 매끄러운 회전 애니메이션을 위해 코드 (및 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가 false가 아닌 경우 위 코드는 글리치를 제공합니다.
나와 같은 세트 애니메이션을 사용하는 경우 세트 태그 안에 보간을 추가해야합니다.
<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>
그것은 나를 위해 일했다.
코 틀린에서 :
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)
})
Is it possible that because you go from 0 to 360, you spend a little bit more time at 0/360 than you are expecting? Perhaps set toDegrees to 359 or 358.
In Android, if you want to animate an object and make it move an object from location1 to location2, the animation API figures out the intermediate locations (tweening) and then queues onto the main thread the appropriate move operations at the appropriate times using a timer. This works fine except that the main thread is usually used for many other things — painting, opening files, responding to user inputs etc. A queued timer can often be delayed. Well written programs will always try to do as many operations as possible in background (non main) threads however you can’t always avoid using the main thread. Operations that require you to operate on a UI object always have to be done on the main thread. Also, many APIs will funnel operations back to the main thread as a form of thread-safety.
Views are all drawn on the same GUI thread which is also used for all user interaction.
So if you need to update GUI rapidly or if the rendering takes too much time and affects user experience then use SurfaceView.
Example of rotation image:
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);
}
}
}
}
}
activity:
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));
}
}
Try to use more than 360 to avoid restarting.
I use 3600 insted of 360 and this works fine for me:
<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%" />
참고URL : https://stackoverflow.com/questions/1634252/how-to-make-a-smooth-image-rotation-in-android
'Programing' 카테고리의 다른 글
MySQL에서 자동 증가 필드를 사용하여 행을 복사하고 동일한 테이블에 삽입하는 방법은 무엇입니까? (0) | 2020.05.05 |
---|---|
`scp`와`rsync`는 어떻게 다릅니 까? (0) | 2020.05.05 |
Hg : git의 rebase와 같은 rebase를 수행하는 방법 (0) | 2020.05.05 |
Windows에서 코드 서명을 위해 자체 서명 된 인증서를 작성하는 방법 (0) | 2020.05.05 |
CFNetwork SSLHandshake가 iOS 9에 실패했습니다 (0) | 2020.05.05 |