본문 바로가기
개발/Android

[Android] Floating Action Button 애니메이션 추가

by Dev Aaron 2020. 11. 8.
반응형

Android에서 Floating Action Button 이하 Fab는 굉장히 자주 사용되는 Widget 중 하나입니다.

현재 사이드 프로젝트로 개발 중인 게임 앱에서도 UI/UX 디자인적 고민을 하다 결국 Fab를 사용하기로 결정했는데, 그 사용법이 이전과는 조금 다릅니다.

이전에는 그냥 우측 하단에 버튼을 위치시키고, 사용자가 버튼을 누르면 무언가 액션을 취하는 식으로 아주 심플하게 사용했는데

이번에는 해당 버튼을 누르면 그 위로 다수의 Fab이 나타나게 구현하려고 합니다. 결과적으로 아래와 같은 UI를 만들려고 합니다.

1. 우선 3개의 Fab를 정의합니다. (res/layout/activity_main.xml)

<androidx.constraintlayout.widget.ConstraintLayout
        ...>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fabSub1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:src="@drawable/ic_lock"
            app:fabSize="mini"
            app:layout_constraintTop_toTopOf="@id/fabMain"
            app:layout_constraintBottom_toBottomOf="@id/fabMain"
            app:layout_constraintStart_toStartOf="@id/fabMain"
            app:layout_constraintEnd_toEndOf="@id/fabMain"/>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fabSub2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:src="@drawable/ic_shopping_cart"
            app:fabSize="mini"
            app:layout_constraintTop_toTopOf="@id/fabMain"
            app:layout_constraintBottom_toBottomOf="@id/fabMain"
            app:layout_constraintStart_toStartOf="@id/fabMain"
            app:layout_constraintEnd_toEndOf="@id/fabMain"/>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fabMain"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="24dp"
            android:src="@drawable/ic_add"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

3개 Fab의 constraint 제약들을 살펴보면 모드 fabMain과 같은 위치에 존재하게 됩니다.

결과적으로 위 상태에서 앱을 실행해보면 fabSub1, fabSub2 버튼은 fabMain에 가려져 보이지 않는 상태입니다. code로 각 버튼들에 setOnClickListener를 붙여 로그를 찍어봐도 fabMain이 모든 click event를 앞에서 먹어버리기 때문에 fabSub1, 2는 무용지물인 상태이죠.

​2. 애니메이션 구현

fabMain 뒤에 가려져 있는 2개의 sub 버튼들에 애니메이션을 적용할 차례입니다. 적용할 애니메이션은 fabMain의 위로 스윽 나오는 애니메이션으로 코드는 다음과 같습니다.

ObjectAnimator.ofFloat(fabSub1, "translationY", -200f).apply { start() }
ObjectAnimator.ofFloat(fabSub2, "translationY", -400f).apply { start() }

ofFloat 함수는 View, String, float type의 3개 인자를 취하고 있습니다.

  1. View는 애니메이션을 적용할 View인 fabSub1, 2를 넣어주면 되고,
  2. String에는 애니메이션의 이동 방향을 의미하는 것 같습니다.
    여기서는 위로 나타나게 할 것이므로 translationY 라고 지정해주었습니다. 이와 다르게 수평 이동을 생각한다면 translationX라고 하면 됩니다. 이 값은 정해진 값으로 임의로 바꾸어서는 안될 것 같습니다.
  3. float 값은 얼마만큼 이동시킬지를 나타내는 값입니다.

위 코드는 Fab버튼을 위로 이동시켜 나타나게 하는데 값이 음수인 것이 의아할 수도 있습니다만, (0, 0) 좌표 체계가 좌측 상단부터 시작되는 것으로 보입니다.

​반대로 위쪽으로 나타난 버튼들을 다시 아래로 숨기기 위해서는 아래와 같이 작성하면 됩니다.

ObjectAnimator.ofFloat(fabSub1, "translationY", 0f).apply { start() }
ObjectAnimator.ofFloat(fabSub2, "translationY", 0f).apply { start() }

이때는 이동 값을 0f로 하였는데요. 저 역시 처음 적용할 때 올렸던 만큼 다시 내리는 것이니 +200f, +400f로 값을 주었는데, 예상과 달리 위로 올라온 만큼 시작 위치에서 아래로 내려가더군요. 즉 0f로 값을 세팅해주어야 최초 위치로 이동하게 된다는 것을 의미하는 것 같습니다.

이게 끝입니다.
어렵지 않을까 싶었는데 생각보다 간단합니다.
​전체 코드는 아래 github repo를 참고하세요.

https://github.com/yoonhok524/Android-Sandbox/tree/master/FabCustom

반응형