-
Notifications
You must be signed in to change notification settings - Fork 0
순차적으로 테두리 채우는 애니메이션
HyeonSeongKang edited this page Aug 29, 2023
·
1 revision
안녕하세요. 안드로이드 팀의 강현성
입니다.
이번 프로젝트에서 순차적으로 테두리를 채우는 애니메이션을 구현했는데 어떻게 구현했는지에 대해서 공유하려 합니다.
먼저 4개의 뷰를 사용하여 각각의 경계선을 나타낸뒤 조건에 따라 보이거나 숨김 상태로 초기를 세팅합니다. (상, 하, 좌, 우)
<!-- Bottom line -->
<View
android:id="@+id/v_bottom_line"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@drawable/shape_bottom_border_line"
android:visibility='@{is_visible == 0 || current_type == "SelfMode" ? View.INVISIBLE : View.VISIBLE}'
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<!-- Right line -->
<View
android:id="@+id/v_right_line"
android:layout_width="2dp"
android:layout_height="match_parent"
android:background="@drawable/shape_right_border_line"
android:visibility='@{is_visible == 0 || current_type == "SelfMode" ? View.INVISIBLE : View.VISIBLE}'
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- Top line -->
<View
android:id="@+id/v_top_line"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@drawable/shape_top_border_line"
android:visibility='@{is_visible == 0 || current_type == "SelfMode" ? View.INVISIBLE : View.VISIBLE}'
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- Left line -->
<View
android:id="@+id/v_left_line"
android:layout_width="2dp"
android:layout_height="match_parent"
android:background="@drawable/shape_left_border_line"
android:visibility='@{is_visible == 0 || current_type == "SelfMode" ? View.INVISIBLE : View.VISIBLE}'
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
- 애니메이션 초기화: 현재 실행 중인 모든 애니메이션을 취소하여 충돌을 방지합니다.
binding.vBottomLine.animate().cancel()
binding.vTopLine.animate().cancel()
binding.vLeftLine.animate().cancel()
binding.vRightLine.animate().cancel()
- 경계선 초기 상태 설정: 각 경계선의 스케일 값을 초기화하여 애니메이션을 시작하기 전의 상태로 설정합니다.
binding.vBottomLine.scaleX = 0f
binding.vTopLine.scaleX = 0f
binding.vLeftLine.scaleY = 0f
binding.vRightLine.scaleY = 0f
- 애니메이션 순서 및 동작:
📍 Pivot: View에서의 회전 또는 확대/축소의 중심점을 나타냅니다. 예를 들어, pivotX가 0f일 때 view는 X축에서 왼쪽 끝을 중심으로 확대/축소됩니다.
🔍 scaleX / scaleY: View의 가로 및 세로 크기를 확대/축소하는 데 사용되는 값입니다. 1f는 원래 크기를 나타내며, 0.5f는 원래 크기의 절반을 나타냅니다.
- 상단 경계선 애니메이션: pivotX를 0f로 설정하고, 가로 스케일을 확장합니다.
binding.vTopLine.pivotX = 0f
binding.vTopLine.animate().setDuration(500).scaleX(1f)
- 우측 경계선 애니메이션: 이전 애니메이션 완료 후, pivotY를 0f로 설정하고, 세로 스케일을 확장합니다.
binding.vRightLine.pivotY = 0f
binding.vRightLine.animate().setDuration(500).scaleY(1f)
- 하단 경계선 애니메이션: 이전 애니메이션 완료 후, pivotX를 경계선의 너비로 설정하고, 가로 스케일을 확장합니다.
binding.vBottomLine.pivotX = binding.vBottomLine.width.toFloat()
binding.vBottomLine.animate().setDuration(500).scaleX(1f)
- **좌측 경계선 애니메이션:**이전 애니메이션 완료 후, pivotY를 경계선의 높이로 설정하고, 세로 스케일을 확장합니다.
binding.vLeftLine.pivotY = binding.vLeftLine.height.toFloat()
binding.vLeftLine.animate().setDuration(500).scaleY(1f)
- 반환 값: 함수는 마지막 애니메이션(좌측 경계선 애니메이션)의 ViewPropertyAnimator를 반환합니다.(withEndAction 사용하기 위해)
return binding.vLeftLine.animate()
fun animateBorder(): ViewPropertyAnimator {
binding.vBottomLine.animate().cancel()
binding.vTopLine.animate().cancel()
binding.vLeftLine.animate().cancel()
binding.vRightLine.animate().cancel()
binding.vBottomLine.scaleX = 0f
binding.vTopLine.scaleX = 0f
binding.vLeftLine.scaleY = 0f
binding.vRightLine.scaleY = 0f
binding.vBottomLine.visibility = visibility
binding.vTopLine.visibility = visibility
binding.vLeftLine.visibility = visibility
binding.vRightLine.visibility = visibility
binding.vTopLine.pivotX = 0f
binding.vTopLine.animate()
.setDuration(500)
.scaleX(1f)
.withEndAction {
binding.vRightLine.pivotY = 0f
binding.vRightLine.animate()
.setDuration(500)
.scaleY(1f)
.withEndAction {
binding.vBottomLine.pivotX = binding.vBottomLine.width.toFloat()
binding.vBottomLine.animate()
.setDuration(500)
.scaleX(1f)
.withEndAction {
binding.vLeftLine.pivotY = binding.vLeftLine.height.toFloat()
binding.vLeftLine.animate()
.setDuration(500)
.scaleY(1f)
}
}
}
return binding.vLeftLine.animate() // 마지막 애니메이션의 애니메이터 반환
}
- FE - 나도 오픈소스 개발자? (NPM 배포기)
- FE - 합성 컴포넌트에 스토리북 한 스푼 🥄
- FE - Tailwind CSS 찐하게 사용해보기
- AOS - 안드로이드 네트워크 연결
- AOS - API 요청에 따른 동적 탭 생성
- AOS - 나도 오픈소스 개발자? (jitpack 배포기)
- AOS - 폭죽 애니메이션
- AOS - 가이드 모드 애니메이션
- AOS - 뷰모델과 애니메이션을 같이 사용했을때의 ISSUE
- BE - 무중단 배포에 대해 알아보자!
- BE - 더 무중단스러운 배포를 위한 graceful shutdown
- BE - 쿼리 최적화에 대해 알아보자!
- BE - 실전, 쿼리 가속도 업!