안녕하세요 아즈라엘 입니다.
안드로이드 애니메이션 좀 허접하자나요..
(게임엔진을 봐서 그런지 더더욱 허접하게 느껴지긴하네요)
이번에 버튼이팩트를 만들기 위해서 버튼을 누르면 아래로 살짝 내려갔다 제자리로 돌아오는것을 만드는데
애니메이션을 순차적으로 할 수 있는게 없을까요?
전그냥 일단 애니메이션을 실행하고 끝나면 다시 애니메이션을 만들어서 또 시작을 하였습니다.
효과는 그럭저럭 되는듯하나..문제는 소스기 누더기 처럼 보여서 보기엔 안좋네요..
좋은 방법 있으시면 같이 공유해요~!!^^
참고로 setFillAfter() 기능은 애니메이션이 끝나면 그 지점에서 멈춰있는겁니다.
private void btnAnimation(final View view) { final float moveY = width / 14.5f; // Animation AnimationSet animSet = new AnimationSet(true); animSet.setInterpolator(new AccelerateDecelerateInterpolator()); animSet.setFillAfter(true); Animation trancelateDown = new TranslateAnimation(0, 0, 0, moveY); trancelateDown.setDuration(250); animSet.addAnimation(trancelateDown); animSet.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { AnimationSet animSet = new AnimationSet(true); animSet.setInterpolator(new AccelerateDecelerateInterpolator()); animSet.setFillAfter(true); Animation trancelateDown = new TranslateAnimation(0, 0, moveY, 0); trancelateDown.setDuration(250); animSet.addAnimation(trancelateDown); animSet.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { switch (view.getId()) { case R.id.btn_calling: DebugUtils.d(TAG, "onAnimationEnd Call"); break; case R.id.btn_habit: DebugUtils.d(TAG, "onAnimationEnd Habit"); break; case R.id.btn_song: DebugUtils.d(TAG, "onAnimationEnd Song"); break; } } }); view.startAnimation(animSet); } }); view.startAnimation(animSet); }
개선 완료
덕분에 라인이 좀 줄긴했네요 ㅋ
private void btnAnimation(final View view) { final float moveY = width / 14.5f; // Animation AnimationSet animSet = new AnimationSet(true); animSet.setInterpolator(new AccelerateDecelerateInterpolator()); animSet.setFillAfter(true); Animation trancelateDown = new TranslateAnimation(0, 0, 0, moveY); trancelateDown.setDuration(250); Animation trancelateUp = new TranslateAnimation(0, 0, 0, -moveY); trancelateUp.setStartOffset(300); trancelateUp.setDuration(250); animSet.addAnimation(trancelateDown); animSet.addAnimation(trancelateUp); animSet.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { switch (view.getId()) { case R.id.btn_calling: DebugUtils.d(TAG, "onAnimationEnd Call"); break; case R.id.btn_habit: DebugUtils.d(TAG, "onAnimationEnd Habit"); break; case R.id.btn_song: DebugUtils.d(TAG, "onAnimationEnd Song"); break; } } }); view.startAnimation(animSet); }
그냥 citrine framework을 쓰시는 것도... 그런 애니 효과는 한두줄일텐데..
요즘 일부 모바일업체에서 도입해서 쓰면서 모바일 제안 단가가 반절까지 떨어지고 있는데... 제안 발표를 하는데 어플을 거의 만들어 오는 시대가 됐으니...쩝..
저도 예전엔 xml로 소스를 리소스화 시키면 마냥 좋을거 같았었는데..
소스의 가독성과 퍼포먼스는 그냥 java로 하는게 제일 좋은거 같더군요..
그리고 xml 안에 있는 파라미터들이 디바이스별, 혹은 사용자의 이벤트에 따라
변하는 경우에는 그닥 좋은 포멧이 아닌거 같아서 그래서 java소스를 선호하고 있습니다.
물론 이식성에서는 리소스화 시켜 놓은게 좋긴 하겠지요..
네이티브 소스들도 이식성을 고려해서 디펜던시 제거해서 개발하면
리소스화 되긴 하지만 프로젝트가 너저분해지면 힘들어지는거 같습니다.
모든게 제 경험이라 이렇다 ~ 라고 단정지을수 없지만 전 요로코롬 하고 있습니다. ㅎㅎ
버튼 동작과 같이 순간적인 press효과는 굳이 애니메이션을 적용해야 하는지 모르겠네요.
프로젝트 특성 상 필요할 수도 있겠지만..
전 그냥 drawable에 selector를 적용한 xml파일로 리소스 로딩 처리를 합니다.
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/back_but_sel"
android:state_pressed="true"
android:state_enabled="true"/>
<item
android:drawable="@drawable/back_but_sel"
android:state_selected="true"
android:state_enabled="true"/>
<item
android:drawable="@drawable/back_but_nor"
android:state_pressed="false"
android:state_enabled="true"/>
<item
android:drawable="@drawable/back_but_nor"
android:state_enabled="false"/>
</selector>
소스를 보시면 아시겠지만.. 버튼을 클릭하면 이미지가 내려갔다 다시 제자리로 돌아옵니다.
마지 줄을 당기면 다시 올라가는것 처럼 ..
그리고 대략 짐작을 하겠지만 width 라는 변수가 있습니다. 이걸 나눠서 사용하죠..
디바이스 마다 이 파라미터가 다 틀려서 상대좌표로 가져옵니다. 즉 가로비율의 몇퍼센트를 세로비율로 사용하기 때문에
에니메이션에서 사용될 moveY 즉 세로 좌표가 일정하게 유지 됩니다.
요즘은 눈높이가 높아져서 단순하게 버튼 클릭했다고 이미지 바뀌면 섭섭해 하더군요
적어도 버튼 누르면 뭔가 효과가 버라이어티 하게 움직이길 원하죠..
음 단순히 버튼을 눌렀는데 아래로 갔다가 위로 올라오는거라면 그냥 애니메이션 set으로 만들어서
애니메이션딜레이를 서로 다르게 해준다음 duration을 적절하게 분배하면 하나의 애니메이션 set으로 깔끔하게 끝날거 같긴하네요