Android Custom Views Animations


Android: Custom Views and Animations

안드로이드 애플리케이션에서 사용자 경험을 개선하고, 더욱 풍부한 인터페이스를 제공하기 위해 커스텀 뷰와 애니메이션을 활용할 수 있습니다. 이 장에서는 커스텀 뷰를 만드는 방법과 애니메이션을 적용하는 다양한 기법에 대해 자세히 설명하겠습니다.

1. 커스텀 뷰 만들기

커스텀 뷰는 안드로이드의 기본 뷰 클래스(View, TextView, ImageView 등)를 상속받아 사용자 정의 동작과 모양을 갖는 뷰를 만드는 것을 말합니다.

커스텀 뷰 만들기 단계
  1. View 클래스 상속 및 생성자 정의
public class CustomView extends View {

    private Paint paint;
    private Path path;

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);

        path = new Path();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth();
        int height = getHeight();

        path.moveTo(0, height / 2);
        path.lineTo(width, height / 2);

        canvas.drawPath(path, paint);
    }
}
  1. 레이아웃 파일에 커스텀 뷰 추가
<!-- res/layout/activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <com.example.CustomView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
  1. 커스텀 뷰 사용
// MainActivity.java
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

2. 애니메이션 기본

애니메이션을 사용하면 뷰의 속성 변화를 부드럽게 보여줄 수 있습니다. 안드로이드에서 기본적으로 제공하는 애니메이션은 ViewPropertyAnimator, ObjectAnimator, 그리고 XML 애니메이션 등이 있습니다.

ViewPropertyAnimator 예제
view.animate()
    .translationX(100)
    .alpha(0.5f)
    .setDuration(1000);
ObjectAnimator 예제
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 100f);
animator.setDuration(1000);
animator.start();
XML 애니메이션 예제
  1. 애니메이션 XML 파일 생성
<!-- res/anim/translate.xml -->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0%"
    android:toXDelta="100%"
    android:duration="1000" />
  1. 애니메이션 적용
Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate);
view.startAnimation(animation);

3. 트랜지션과 애니메이터

트랜지션 프레임워크

트랜지션 프레임워크는 화면 간의 전환 효과를 적용하는 데 사용됩니다. 기본적인 트랜지션 종류에는 Fade, Slide, Explode 등이 있습니다.

Transition fade = new Fade();
fade.setDuration(1000);
TransitionManager.beginDelayedTransition(sceneRoot, fade);
애니메이터

애니메이터는 Animator 클래스의 서브클래스를 사용하여 다양한 애니메이션 효과를 제공할 수 있습니다. 대표적인 예로 ValueAnimator, ObjectAnimator 등이 있습니다.

ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
animator.setDuration(1000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float value = (float) animation.getAnimatedValue();
        view.setAlpha(value);
    }
});
animator.start();

4. 커스텀 애니메이션

복잡한 애니메이션을 구현하려면 AnimatorSet을 사용하여 여러 애니메이션을 함께 사용할 수 있습니다.

ObjectAnimator moveX = ObjectAnimator.ofFloat(view, "translationX", 100f);
ObjectAnimator fadeIn = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f);

AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(moveX, fadeIn);
animatorSet.setDuration(1000);
animatorSet.start();

예제 종합

커스텀 뷰와 애니메이션 통합 예제

  1. 커스텀 뷰 구현
public class AnimatedCustomView extends View {

    private Paint paint;
    private float radius = 0f;

    public AnimatedCustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setColor(Color.BLUE);
        paint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth();
        int height = getHeight();
        canvas.drawCircle(width / 2, height / 2, radius, paint);
    }

    public void animateRadius() {
        ValueAnimator animator = ValueAnimator.ofFloat(0f, Math.min(getWidth(), getHeight()) / 2);
        animator.setDuration(1000);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                radius = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        animator.start();
    }
}
  1. 레이아웃 파일에 커스텀 뷰 추가
<!-- res/layout/activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <com.example.AnimatedCustomView
        android:id="@+id/animatedCustomView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Animate"
        android:onClick="startAnimation"/>
</LinearLayout>
  1. 애니메이션 시작 버튼 구현
// MainActivity.java
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private AnimatedCustomView animatedCustomView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        animatedCustomView = findViewById(R.id.animatedCustomView);
    }

    public void startAnimation(View view) {
        animatedCustomView.animateRadius();
    }
}

요약

이 장에서는 안드로이드 애플리케이션에서 커스텀 뷰를 만들고 애니메이션을 적용하는 방법에 대해 알아보았습니다. 이를 통해 앱의 UI를 더욱 풍부하고 사용자 친화적으로 만들 수 있습니다. 다양한 애니메이션 기법과 트랜지션을 활용하여 사용자가 즐길 수 있는 동적인 인터페이스를 구현해 보세요.


Leave a Reply

Your email address will not be published. Required fields are marked *