• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.android.setupdesign.view
18 
19 import android.animation.Animator
20 import android.animation.Animator.AnimatorListener
21 import android.content.Context
22 import android.util.AttributeSet
23 import android.view.View
24 import androidx.annotation.StringRes
25 import androidx.core.view.AccessibilityDelegateCompat
26 import androidx.core.view.ViewCompat
27 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
28 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
29 import com.airbnb.lottie.LottieAnimationView
30 import com.google.android.setupcompat.util.Logger
31 
32 /** A [LottieAnimationView] that take response to pause and resume animation when user clicks. */
33 class SudLottieAnimationView
34 @JvmOverloads
35 constructor(context: Context, attrs: AttributeSet? = null) :
36   LottieAnimationView(context, attrs),
37   View.OnClickListener,
38   AnimatorListener,
39   Animator.AnimatorPauseListener {
40   var clickListener: OnClickListener? = null
41 
42   private val actionInfoAnimatorPlaying =
43     buildAccessibilityAction(R.string.sud_lottie_animation_view_accessibility_action_pause)
44 
45   private val actionInfoAnimatorPaused =
46     buildAccessibilityAction(R.string.sud_lottie_animation_view_accessibility_action_resume)
47 
48   init {
49     super.setOnClickListener(this)
50     setContentDescription(
51       resources.getString(R.string.sud_lottie_animation_view_accessibility_description)
52     )
53     addAnimatorListener(this)
54     addAnimatorPauseListener(this)
55   }
56 
buildAccessibilityActionnull57   private fun buildAccessibilityAction(@StringRes stringId: Int) =
58     AccessibilityActionCompat(
59       AccessibilityNodeInfoCompat.ACTION_CLICK,
60       resources.getString(stringId),
61     )
62 
63   override fun setOnClickListener(listener: OnClickListener?) {
64     clickListener = listener
65   }
66 
setAccessibilityDelegatenull67   private fun setAccessibilityDelegate(
68     accessibilityAction: AccessibilityNodeInfoCompat.AccessibilityActionCompat
69   ) {
70     ViewCompat.setAccessibilityDelegate(
71       this,
72       object : AccessibilityDelegateCompat() {
73         override fun onInitializeAccessibilityNodeInfo(
74           host: View,
75           info: AccessibilityNodeInfoCompat,
76         ) {
77           super.onInitializeAccessibilityNodeInfo(host, info)
78           info.addAction(accessibilityAction)
79         }
80       },
81     )
82   }
83 
onClicknull84   override fun onClick(v: View) {
85     clickListener?.onClick(v)
86     if (isAnimating) {
87       pauseAnimation()
88     } else {
89       resumeAnimation()
90     }
91   }
92 
onAnimationPausenull93   override fun onAnimationPause(animation: Animator) {
94     LOG.atInfo("onAnimationPause")
95     setAccessibilityDelegate(actionInfoAnimatorPaused)
96   }
97 
onAnimationResumenull98   override fun onAnimationResume(animation: Animator) {
99     LOG.atInfo("onAnimationResume")
100     setAccessibilityDelegate(actionInfoAnimatorPlaying)
101   }
102 
onAnimationStartnull103   override fun onAnimationStart(animation: Animator) {
104     LOG.atInfo("onAnimationStart")
105     setAccessibilityDelegate(actionInfoAnimatorPlaying)
106   }
107 
onAnimationEndnull108   override fun onAnimationEnd(animation: Animator) {
109     // Do nothing
110   }
111 
onAnimationCancelnull112   override fun onAnimationCancel(animation: Animator) {
113     // Do nothing
114   }
115 
onAnimationRepeatnull116   override fun onAnimationRepeat(animation: Animator) {
117     // Do nothing
118   }
119 
120   private companion object {
121     val LOG = Logger(SudLottieAnimationView::class.java)
122   }
123 }
124