• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.android.wallpaper.picker.customization.ui.view.animator
18 
19 import android.animation.ValueAnimator
20 import androidx.core.animation.addListener
21 import androidx.core.animation.doOnEnd
22 import androidx.recyclerview.widget.DefaultItemAnimator
23 import androidx.recyclerview.widget.RecyclerView.State
24 import androidx.recyclerview.widget.RecyclerView.ViewHolder
25 import com.android.wallpaper.R
26 import com.android.wallpaper.picker.customization.ui.view.adapter.FloatingToolbarTabAdapter.TabViewHolder
27 
28 class TabItemAnimator : DefaultItemAnimator() {
29 
canReuseUpdatedViewHoldernull30     override fun canReuseUpdatedViewHolder(viewHolder: ViewHolder, payloads: MutableList<Any>) =
31         true
32 
33     override fun recordPreLayoutInformation(
34         state: State,
35         viewHolder: ViewHolder,
36         changeFlags: Int,
37         payloads: MutableList<Any>,
38     ): ItemHolderInfo {
39         if (changeFlags == FLAG_CHANGED && payloads.isNotEmpty()) {
40             return when (payloads[0] as? Int) {
41                 SELECT_ITEM -> TabItemHolderInfo(true)
42                 UNSELECT_ITEM -> TabItemHolderInfo(false)
43                 else -> super.recordPreLayoutInformation(state, viewHolder, changeFlags, payloads)
44             }
45         }
46         return super.recordPreLayoutInformation(state, viewHolder, changeFlags, payloads)
47     }
48 
animateChangenull49     override fun animateChange(
50         oldHolder: ViewHolder,
51         newHolder: ViewHolder,
52         preLayoutInfo: ItemHolderInfo,
53         postLayoutInfo: ItemHolderInfo,
54     ): Boolean {
55         if (preLayoutInfo is TabItemHolderInfo && newHolder is TabViewHolder) {
56             newHolder.itemView.post {
57                 val iconSize =
58                     newHolder.itemView.resources.getDimensionPixelSize(
59                         R.dimen.floating_tab_toolbar_tab_icon_size
60                     )
61                 ValueAnimator.ofFloat(
62                         if (preLayoutInfo.selectItem) 0f else 1f,
63                         if (preLayoutInfo.selectItem) 1f else 0f,
64                     )
65                     .apply {
66                         addUpdateListener {
67                             val value = it.animatedValue as Float
68                             newHolder.icon.layoutParams =
69                                 newHolder.icon.layoutParams.apply {
70                                     width = (value * iconSize).toInt()
71                                 }
72                             newHolder.container.background.alpha =
73                                 (value * BACKGROUND_ALPHA_MAX).toInt()
74                         }
75                         addListener { doOnEnd { dispatchAnimationFinished(newHolder) } }
76                         duration = ANIMATION_DURATION_MILLIS
77                     }
78                     .start()
79             }
80             return true
81         }
82 
83         return super.animateChange(oldHolder, newHolder, preLayoutInfo, postLayoutInfo)
84     }
85 
86     class TabItemHolderInfo(val selectItem: Boolean) : ItemHolderInfo()
87 
88     companion object {
89         const val SELECT_ITEM = 3024
90         const val UNSELECT_ITEM = 1114
91         const val BACKGROUND_ALPHA_MAX = 255
92         const val ANIMATION_DURATION_MILLIS = 200L
93     }
94 }
95