1 /* 2 * Copyright (C) 2023 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.systemui.statusbar.phone.fragment 18 19 import android.view.View 20 import androidx.core.animation.Interpolator 21 import androidx.core.animation.ValueAnimator 22 import com.android.app.animation.InterpolatorsAndroidX 23 24 /** 25 * A controller that keeps track of multiple sources applying alpha value changes to a view. It will 26 * always apply the minimum alpha value of all sources. 27 */ 28 internal class MultiSourceMinAlphaController 29 @JvmOverloads 30 constructor(private val view: View, private val initialAlpha: Float = 1f) { 31 32 private val alphas = mutableMapOf<Int, Float>() 33 private val animators = mutableMapOf<Int, ValueAnimator>() 34 35 /** 36 * Sets the alpha of the provided source and applies it to the view (if no other source has set 37 * a lower alpha currently). If an animator of the same source is still running (i.e. 38 * [animateToAlpha] was called before), that animator is cancelled. 39 */ setAlphanull40 fun setAlpha(alpha: Float, sourceId: Int) { 41 animators[sourceId]?.cancel() 42 updateAlpha(alpha, sourceId) 43 } 44 45 /** Animates to the alpha of the provided source. */ animateToAlphanull46 fun animateToAlpha( 47 alpha: Float, 48 sourceId: Int, 49 duration: Long, 50 interpolator: Interpolator = InterpolatorsAndroidX.ALPHA_IN, 51 startDelay: Long = 0 52 ) { 53 animators[sourceId]?.cancel() 54 val animator = ValueAnimator.ofFloat(getMinAlpha(), alpha) 55 animator.duration = duration 56 animator.startDelay = startDelay 57 animator.interpolator = interpolator 58 animator.addUpdateListener { updateAlpha(animator.animatedValue as Float, sourceId) } 59 animator.start() 60 animators[sourceId] = animator 61 } 62 resetnull63 fun reset() { 64 alphas.clear() 65 animators.forEach { it.value.cancel() } 66 animators.clear() 67 applyAlphaToView() 68 } 69 updateAlphanull70 private fun updateAlpha(alpha: Float, sourceId: Int) { 71 alphas[sourceId] = alpha 72 applyAlphaToView() 73 } 74 applyAlphaToViewnull75 private fun applyAlphaToView() { 76 val minAlpha = getMinAlpha() 77 view.visibility = if (minAlpha != 0f) View.VISIBLE else View.INVISIBLE 78 view.alpha = minAlpha 79 } 80 <lambda>null81 private fun getMinAlpha() = alphas.minOfOrNull { it.value } ?: initialAlpha 82 } 83