애니메이션과 함께 뷰 이동

사용자 상호작용 또는 백그라운드에서의 처리로 인해 화면 객체의 위치를 변경해야 하는 경우가 많습니다. 객체의 위치를 즉시 업데이트하여 한 영역에서 다른 영역으로 깜박이게 하는 대신 애니메이션을 사용하여 객체를 시작 위치에서 종료 위치로 이동합니다.

Android에서 화면에서 뷰 객체의 위치를 변경할 수 있는 한 가지 방법은 ObjectAnimator를 사용하는 것입니다. 객체가 놓이도록 할 종료 위치와 애니메이션 재생 시간을 제공합니다. 시간 보간기를 사용하여 애니메이션의 가속 또는 감속을 제어할 수도 있습니다.

ObjectAnimator로 뷰 위치 변경

ObjectAnimator API를 사용하면 지정된 기간으로 뷰의 속성을 변경할 수 있습니다. 이 API에는 애니메이션을 적용하는 속성의 유형에 따라 ObjectAnimator의 인스턴스를 만들 수 있는 정적 메서드가 포함되어 있습니다. 화면에서 뷰 위치를 변경할 때는 translationX 속성과 translationY 속성을 사용합니다.

다음은 2초 동안 화면 왼쪽에서 100픽셀 위치로 뷰를 이동하는 ObjectAnimator의 예입니다.

Kotlin

ObjectAnimator.ofFloat(view, "translationX", 100f).apply {
    duration = 2000
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f);
animation.setDuration(2000);
animation.start();

이 예에서는 변환 값이 부동 소수점 수여야 하므로 ObjectAnimator.ofFloat() 메서드를 사용합니다. 첫 번째 매개변수는 애니메이션을 적용할 뷰입니다. 두 번째 매개변수는 애니메이션을 적용할 속성입니다. 뷰를 가로로 이동해야 하므로 translationX 속성이 사용됩니다. 마지막 매개변수는 애니메이션의 끝 값입니다. 이 예에서 값 100은 화면 왼쪽에서 몇 픽셀만큼 떨어진 위치를 나타냅니다.

다음 메서드는 애니메이션에 걸리는 시간(밀리초)을 지정합니다. 이 예에서 애니메이션은 2초 (2, 000밀리초) 동안 실행됩니다.

마지막 메서드로 인해 애니메이션이 실행되어 화면에서 뷰의 위치가 업데이트됩니다.

ObjectAnimator 사용에 관한 자세한 내용은 ObjectAnimator를 사용하여 애니메이션 처리를 참고하세요.

곡선 모션 추가

ObjectAnimator를 사용하면 편리하지만 기본적으로 시작점과 종료점 사이의 직선을 따라 뷰 위치가 변경됩니다. 머티리얼 디자인은 화면에서 객체의 공간 이동 및 애니메이션 타이밍에 곡선을 사용합니다. 곡선 모션을 사용하면 앱에 질감을 더하고 애니메이션을 더 흥미롭게 만들 수 있습니다.

자체 경로 정의

ObjectAnimator 클래스에는 경로와 함께 한 번에 두 개 이상의 속성을 사용하여 좌표를 애니메이션할 수 있는 생성자가 있습니다. 예를 들어 다음 애니메이터는 Path 객체를 사용하여 뷰의 X 및 Y 속성에 애니메이션을 적용합니다.

Kotlin

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    val path = Path().apply {
        arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true)
    }
    val animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path).apply {
        duration = 2000
        start()
    }
} else {
    // Create animator without using curved path
}

Java

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  Path path = new Path();
  path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true);
  ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
  animator.setDuration(2000);
  animator.start();
} else {
  // Create animator without using curved path
}

다음은 원호 애니메이션의 모습입니다.

그림 1. 곡선 경로 애니메이션

Interpolator는 이징 곡선의 구현입니다. 이징 곡선의 개념에 관한 자세한 내용은 Material Design 문서를 참고하세요. Interpolator은 애니메이션의 특정 값이 시간의 함수로 계산되는 방식을 정의합니다. 시스템은 Material Design 사양에서 세 가지 기본 곡선에 관한 XML 리소스를 제공합니다.

  • @interpolator/fast_out_linear_in.xml
  • @interpolator/fast_out_slow_in.xml
  • @interpolator/linear_out_slow_in.xml

PathInterpolator 사용

PathInterpolator 클래스는 Android 5.0 (API 21)에 도입된 보간기입니다. 이 클래스는 베지어 곡선 또는 Path 객체를 기반으로 합니다. 이징 관련 Material Design 문서의 Android 예에서는 PathInterpolator를 사용합니다.

PathInterpolator에는 다양한 유형의 베지어 곡선을 기반으로 하는 생성자가 있습니다. 모든 베지어 곡선은 시작점과 끝점이 각각 (0,0)(1,1)에 고정되어 있습니다. 다른 생성자 인수는 생성 중인 베지어 곡선 유형에 따라 다릅니다.

예를 들어 이차 베지어 곡선의 경우 제어점 한 개의 X 및 Y 좌표만 필요합니다.

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    PathInterpolator(0.67f, 0.33f)
} else {
    LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  myInterpolator = new PathInterpolator(0.67f, 0.33f);
} else {
  myInterpolator = new LinearInterpolator();
}

이렇게 하면 빠르게 시작했다가 끝에 가까워질수록 감속하는 이징 곡선이 생성됩니다.

3차원 베지어 생성자에도 시작점과 끝점이 고정되어 있지만, 다음과 같은 두 가지 제어점이 필요합니다.

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    PathInterpolator(0.5f, 0.7f, 0.1f, 1.0f)
} else {
    LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  myInterpolator = new PathInterpolator(0.5f, 0.7f, 0.1f, 1.0f);
} else {
  myInterpolator = new LinearInterpolator();
}

Material Design 강조된 감속 이징 곡선을 구현한 것입니다.

보다 세밀하게 제어하려면 곡선을 정의하는 데 임의의 Path를 사용할 수 있습니다.

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  val path = Path().apply {
    moveTo(0.0f, 0.0f)
    cubicTo(0.5f, 0.7f, 0.1f, 1.0f, 1.0f, 1.0f)
  }
  PathInterpolator(path)
} else {
  LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  Path path = new Path();
  path.moveTo(0.0f, 0.0f);
  path.cubicTo(0.5f, 0.7f, 0.1f, 1.0f, 1.0f, 1.0f);
  myInterpolator = new PathInterpolator(path);
} else {
  myInterpolator = new LinearInterpolator();
}

이렇게 하면 3차원 베지어 예와 동일한 이징 곡선이 생성되지만, 대신 Path을 사용합니다.

또한 경로 보간 유형을 XML 리소스로 정의할 수도 있습니다.

<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:controlX1="0.5"
    android:controlY1="0.7"
    android:controlX2="0.1f"
    android:controlY2="1.0f"/>

PathInterpolator 객체를 만든 후 Animator.setInterpolator() 메서드에 전달할 수 있습니다. Animator는 시작 시 보간기를 사용하여 시간 또는 경로 곡선을 결정합니다.

Kotlin

val animation = ObjectAnimator.ofFloat(view, "translationX", 100f).apply {
    interpolator = myInterpolator
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f);
animation.setInterpolator(myInterpolator);
animation.start();