programing

Android : 완료 후 애니메이션 위치 재설정

nasanasas 2020. 11. 22. 19:51
반응형

Android : 완료 후 애니메이션 위치 재설정


xml 정의 애니메이션을 사용하여 화면에서보기를 슬라이드합니다. 문제는 애니메이션이 완료 되 자마자 원래 위치로 재설정된다는 것입니다. 이 문제를 해결하는 방법을 알아야합니다. 다음은 xml입니다.

<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator">
   <translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="500"/></set>

다음은이를 호출하는 데 사용하는 Java입니다.

    homeScrn = (View)findViewById(R.id.homescreen);
    slideLeftOut = AnimationUtils.loadAnimation(this, R.anim.slide_left_out);

    //Set Click Listeners For Menu
    btnHelp.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            LayoutInflater.from(getApplicationContext()).inflate(R.layout.help, (ViewGroup)findViewById(R.id.subpage), true);
            homeScrn.startAnimation(slideLeftOut);
        }
    });

그래서 기본적으로 일어나는 일은 하나 아래에 뷰를 부 풀리는 것입니다. 그런 다음 왼쪽 상단의 뷰를 애니메이션합니다. 화면에서 벗어나 애니메이션이 끝나 자마자 위치를 원래대로 되돌립니다.


애니메이션이 예상대로 작동합니다. 무언가를 애니메이션했다고해서 실제로 움직 인 것은 아닙니다. 애니메이션은 위젯의 구성이 아니라 애니메이션 자체 중에 그려진 픽셀에만 영향을줍니다.

를 추가해야 AnimationListener하고 onAnimationEnd()메서드에서 이동을 영구적으로 만드는 작업을 수행해야합니다 (예 : 상위 뷰에서 상위 뷰를 제거하고 상단 뷰를 가시성을 갖는 것으로 표시 GONE).


마지막으로 해결 방법을 찾았습니다. 올바른 방법은 다음과 같습니다 setFillAfter(true).

XML로 애니메이션을 정의하려면 다음과 같이해야합니다.

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

    <translate 
        android:fromXDelta="0%"
        android:toXDelta="-100%"
        android:duration="1000"/>

</set>

내가 태그에 정의한 것을 볼 수 있습니다 filterAfter="true". set태그에 정의하려고하면 translate작동하지 않습니다 . 프레임 워크 버그 일 수 있습니다 !!

그리고 코드에서

Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_out);
someView.startAnimation(anim);

또는

TranslateAnimation animation = new TranslateAnimation(-90, 150, 0, 0);

animation.setFillAfter(true);

animation.setDuration(1800);

someView.startAnimation(animation);

그럼 확실히 작동합니다 !!

이제보기가 실제로 새 위치로 이동하는 것처럼 보이지만 실제로보기의 픽셀이 이동하는 것처럼 보입니다. 즉,보기가 실제로 초기 위치에 있지만 표시되지 않습니다. 버튼이 있으면 테스트 할 수 있습니다. 보기 / 레이아웃을 새 위치로 수동으로 이동해야하는 문제를 수정하려면보기 (제 경우에는 레이아웃)에서 클릭 가능한보기

public TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)

new TranslateAnimation(-90, 150, 0, 0);

이제 애니메이션이 -90 x 축에서 150 x 축으로 시작하는 것을 볼 수 있습니다.

그래서 우리가하는 일은

someView.setAnimationListener(this);

그리고

public void onAnimationEnd(Animation animation)
{
   someView.layout(150, 0, someView.getWidth() + 150, someView.getHeight());
}

이제 설명하겠습니다 public void layout (int left, int top, int right, int botton)

그것은 새로운 위치 첫 번째 인수로 레이아웃 우리가 왼쪽, 정의로 이동 (150) 에 우리의보기를 애니메이션 한 애니메이션을 번역하기 때문에, 150 x 축 , 상단이 0 인 우리가 바로 지금 우리가했던, y 축 애니메이션하지 않았기 때문에 someView.getWidth() + 150기본적으로 뷰의 너비를 얻고 150을 추가했습니다. 왜냐하면 왼쪽은 이제 뷰 너비를 원래의 너비로 만들기 위해 150 x 축 으로 이동 하고 아래쪽은 뷰의 높이와 같기 때문입니다.

사람들이 이제 번역의 개념을 이해했으면 좋겠습니다. 여전히 의견 섹션에서 즉시 질문 할 수있는 질문이 있으시면 도움을 드리겠습니다. :)

편집layout() 보기가 무효화되고 변경 사항이 유지되지 않을 때 프레임 워크에서 호출 할 수 있으므로 메서드를 사용하지 마십시오. LayoutParams요구 사항에 따라 레이아웃 매개 변수를 설정 하는 사용 합니다.


회신이 조금 늦을 수 있지만 이에 대한 해결책이 있습니다.

android:fillAfter="true"XML에 추가 하기 만하면됩니다.


당신이 사용할 수있는

fillAfter=true
fillEnabled=true

뷰가 원래 위치로 재설정되지는 않지만 뷰에 버튼이나 다른 것이 있으면 위치가 변경되지 않습니다.

을 사용해야 ObjectAnimator하며 API 11 수준에서 작동합니다. 뷰 위치를 자동으로 변경합니다.

여기에 예가 있습니다

ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(mContent_container, "translationX", startX, endX);
objectAnimator.setDuration(1000);
objectAnimator.start();

그의 답변에 감사드립니다.

앱을 찾을 수없는 경우 object animator,에서 API 레벨을 변경 Project -> properties -> Android보다,import android.animation.ObjectAnimator;

감사합니다 Hayk


다음 명령을 추가해야합니다.

final Animation animSlideLeft = new TranslateAnimation(0, -80, 0,-350, 0, 0, 0, 0);
animSlideLeft.setFillAfter(true);

나는 같은 질문에 가서 OnAnimationEnd ()에서 marginLeft를 설정하여 해결했습니다 ..

MarginLayoutParams params = (MarginLayoutParams) this.getLayoutParams(); params.setMargins(this.getWidth()*position, 0,0,0); this.setLayoutParams(params);


이 문제는 일주일 이상 괴로워했습니다. 그리고 무함마드의 대답은 나에게 그것을 해결하는 확실한 방법을 지적했다.

애니메이션과 함께 사이드 메뉴를 구현하기 위해 서버 레이아웃을 사용했습니다. "view.layout은 영구적이지 않습니다. 영구적 인 LayoutParams를 사용해야합니다."

내 솔루션은 다음과 같습니다. (어떤 종류의 LayoutParameter가 부모의 레이아웃에 따라 달라지는 지 사용하십시오) :

@Override
public void onAnimationEnd(Animation animation) {
FrameLayout.LayoutParams layoutParams=new FrameLayout.LayoutParams(screenWidth, screenHeight);
layoutParams.setMargins((int) -(screenWidth * RATE), 0,
            (int) (screenWidth - screenWidth * RATE), screenHeight);
    for(View v:views) {

        v.setLayoutParams(layoutParams);
        //v.layout((int) -(screenWidth * RATE), 0, (int) (screenWidth - screenWidth * RATE), screenHeight);
        v.clearAnimation();
    }
}

사용 도우미 방법을 쉽게보기 애니메이션을 아래에. 그런 다음 완료 후 다음 과 같이 애니메이션하고 재설정 할 수 있습니다 .

// Animate the view:

fly(
  view1,
  (float) 0,
  (float) 0,
  (float) 0,
  (float) 1000,
  250,
  null,
  null,
  () -> {

    // Return the view to initial position on animation end:  

    fly(
      view1,
      (float) 0,
      (float) 0,
      (float) 0,
      (float) 0,
      0);

    return null;
  });

도우미 방법 :

/**
 * Translation of a view.
 */
public static void fly(
  View view,
  float fromXDelta,
  float toXDelta,
  float fromYDelta,
  float toYDelta,
  int duration) {

  fly(
    view,
    fromXDelta,
    toXDelta,
    fromYDelta,
    toYDelta,
    duration,
    null,
    null,
    null);
}

/**
 * Translation of a view with handlers.
 *
 * @param view       A view to animate.
 * @param fromXDelta Amount to shift by X axis for start position.
 * @param toXDelta   Amount to shift by X axis for end position.
 * @param fromYDelta Amount to shift by Y axis for start position.
 * @param toYDelta   Amount to shift by Y axis for end position.
 * @param duration   Animation duration.
 * @param start      On animation start. Otherwise NULL.
 * @param repeat     On animation repeat. Otherwise NULL.
 * @param end        On animation end. Otherwise NULL.
 */
public static void fly(
  View view,
  float fromXDelta,
  float toXDelta,
  float fromYDelta,
  float toYDelta,
  int duration,
  Callable start,
  Callable repeat,
  Callable end) {

  Animation animation;

  animation =
    new TranslateAnimation(
      fromXDelta,
      toXDelta,
      fromYDelta,
      toYDelta);

  animation.setDuration(
    duration);

  animation.setInterpolator(
    new DecelerateInterpolator());

  animation.setFillAfter(true);

  view.startAnimation(
    animation);

  animation.setAnimationListener(new AnimationListener() {

    @Override
    public void onAnimationStart(Animation animation) {

      if (start != null) {
        try {

          start.call();

        } catch (Exception e) {
          e.printStackTrace();
        }
      }

    }

    @Override
    public void onAnimationEnd(Animation animation) {

      if (end != null) {
        try {

          end.call();

        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }

    @Override
    public void onAnimationRepeat(
      Animation animation) {

      if (repeat != null) {
        try {

          repeat.call();

        } catch (Exception e) {
          e.printStackTrace();
        }
      }  
    }
  });
}

참고 URL : https://stackoverflow.com/questions/3882826/android-animation-position-resets-after-complete

반응형