Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt +104 −86 Original line number Diff line number Diff line Loading @@ -86,15 +86,56 @@ class ClockSizeTransition( transition.values[SMARTSPACE_BOUNDS] = targetSSView.getRect() } open fun mutateBounds( view: View, fromIsVis: Boolean, toIsVis: Boolean, fromBounds: Rect, toBounds: Rect, fromSSBounds: Rect?, toSSBounds: Rect?, ) {} open fun initTargets(from: Target, to: Target) {} open fun mutateTargets(from: Target, to: Target) {} data class Target( var view: View, var visibility: Int, var isVisible: Boolean, var alpha: Float, var bounds: Rect, var ssBounds: Rect?, ) { companion object { fun fromStart(startValues: TransitionValues): Target { var fromVis = startValues.values[PROP_VISIBILITY] as Int var fromIsVis = fromVis == View.VISIBLE var fromAlpha = startValues.values[PROP_ALPHA] as Float // Align starting visibility and alpha if (!fromIsVis) fromAlpha = 0f else if (fromAlpha <= 0f) { fromIsVis = false fromVis = View.INVISIBLE } return Target( view = startValues.view, visibility = fromVis, isVisible = fromIsVis, alpha = fromAlpha, bounds = startValues.values[PROP_BOUNDS] as Rect, ssBounds = startValues.values[SMARTSPACE_BOUNDS] as Rect?, ) } fun fromEnd(endValues: TransitionValues): Target { val toVis = endValues.values[PROP_VISIBILITY] as Int val toIsVis = toVis == View.VISIBLE return Target( view = endValues.view, visibility = toVis, isVisible = toIsVis, alpha = if (toIsVis) 1f else 0f, bounds = endValues.values[PROP_BOUNDS] as Rect, ssBounds = endValues.values[SMARTSPACE_BOUNDS] as Rect?, ) } } } override fun createAnimator( sceenRoot: ViewGroup, Loading @@ -109,72 +150,58 @@ class ClockSizeTransition( return null } var fromVis = startValues.values[PROP_VISIBILITY] as Int var fromIsVis = fromVis == View.VISIBLE var fromAlpha = startValues.values[PROP_ALPHA] as Float val fromBounds = startValues.values[PROP_BOUNDS] as Rect val fromSSBounds = startValues.values[SMARTSPACE_BOUNDS] as Rect? val toView = endValues.view val toVis = endValues.values[PROP_VISIBILITY] as Int val toBounds = endValues.values[PROP_BOUNDS] as Rect val toSSBounds = endValues.values[SMARTSPACE_BOUNDS] as Rect? val toIsVis = toVis == View.VISIBLE val toAlpha = if (toIsVis) 1f else 0f val from = Target.fromStart(startValues) val to = Target.fromEnd(endValues) initTargets(from, to) mutateTargets(from, to) // Align starting visibility and alpha if (!fromIsVis) fromAlpha = 0f else if (fromAlpha <= 0f) { fromIsVis = false fromVis = View.INVISIBLE } mutateBounds(toView, fromIsVis, toIsVis, fromBounds, toBounds, fromSSBounds, toSSBounds) if (fromIsVis == toIsVis && fromBounds.equals(toBounds)) { if (from.isVisible == to.isVisible && from.bounds.equals(to.bounds)) { if (DEBUG) { Log.w( TAG, "Skipping no-op transition: $toView; " + "vis: $fromVis -> $toVis; " + "alpha: $fromAlpha -> $toAlpha; " + "bounds: $fromBounds -> $toBounds; ", "Skipping no-op transition: ${to.view}; " + "vis: ${from.visibility} -> ${to.visibility}; " + "alpha: ${from.alpha} -> ${to.alpha}; " + "bounds: ${from.bounds} -> ${to.bounds}; ", ) } return null } val sendToBack = fromIsVis && !toIsVis val sendToBack = from.isVisible && !to.isVisible fun lerp(start: Int, end: Int, fract: Float): Int = MathUtils.lerp(start.toFloat(), end.toFloat(), fract).toInt() fun computeBounds(fract: Float): Rect = Rect( lerp(fromBounds.left, toBounds.left, fract), lerp(fromBounds.top, toBounds.top, fract), lerp(fromBounds.right, toBounds.right, fract), lerp(fromBounds.bottom, toBounds.bottom, fract), lerp(from.bounds.left, to.bounds.left, fract), lerp(from.bounds.top, to.bounds.top, fract), lerp(from.bounds.right, to.bounds.right, fract), lerp(from.bounds.bottom, to.bounds.bottom, fract), ) fun assignAnimValues(src: String, fract: Float, vis: Int? = null) { mutateTargets(from, to) val bounds = computeBounds(fract) val alpha = MathUtils.lerp(fromAlpha, toAlpha, fract) val alpha = MathUtils.lerp(from.alpha, to.alpha, fract) if (DEBUG) { Log.i( TAG, "$src: $toView; fract=$fract; alpha=$alpha; vis=$vis; bounds=$bounds;", "$src: ${to.view}; fract=$fract; alpha=$alpha; vis=$vis; bounds=$bounds;", ) } toView.setVisibility(vis ?: View.VISIBLE) toView.setAlpha(alpha) toView.setRect(bounds) to.view.setVisibility(vis ?: View.VISIBLE) to.view.setAlpha(alpha) to.view.setRect(bounds) } if (DEBUG) { Log.i( TAG, "transitioning: $toView; " + "vis: $fromVis -> $toVis; " + "alpha: $fromAlpha -> $toAlpha; " + "bounds: $fromBounds -> $toBounds; ", "transitioning: ${to.view}; " + "vis: ${from.visibility} -> ${to.visibility}; " + "alpha: ${from.alpha} -> ${to.alpha}; " + "bounds: ${from.bounds} -> ${to.bounds}; ", ) } Loading @@ -190,11 +217,11 @@ class ClockSizeTransition( this@VisibilityBoundsTransition.addListener( object : TransitionListenerAdapter() { override fun onTransitionStart(t: Transition) { toView.viewTreeObserver.addOnPreDrawListener(predrawCallback) to.view.viewTreeObserver.addOnPreDrawListener(predrawCallback) } override fun onTransitionEnd(t: Transition) { toView.viewTreeObserver.removeOnPreDrawListener(predrawCallback) to.view.viewTreeObserver.removeOnPreDrawListener(predrawCallback) } } ) Loading @@ -202,17 +229,17 @@ class ClockSizeTransition( val listener = object : AnimatorListenerAdapter() { override fun onAnimationStart(anim: Animator) { assignAnimValues("start", 0f, fromVis) assignAnimValues("start", 0f, from.visibility) } override fun onAnimationEnd(anim: Animator) { assignAnimValues("end", 1f, toVis) if (sendToBack) toView.translationZ = 0f assignAnimValues("end", 1f, to.visibility) if (sendToBack) to.view.translationZ = 0f } } anim.addListener(listener) assignAnimValues("init", 0f, fromVis) assignAnimValues("init", 0f, from.visibility) } } Loading Loading @@ -251,31 +278,23 @@ class ClockSizeTransition( } } override fun mutateBounds( view: View, fromIsVis: Boolean, toIsVis: Boolean, fromBounds: Rect, toBounds: Rect, fromSSBounds: Rect?, toSSBounds: Rect?, ) { override fun initTargets(from: Target, to: Target) { // Move normally if clock is not changing visibility if (fromIsVis == toIsVis) return if (from.isVisible == to.isVisible) return fromBounds.set(toBounds) from.bounds.set(to.bounds) if (isLargeClock) { // Large clock shouldn't move; fromBounds already set } else if (toSSBounds != null && fromSSBounds != null) { } else if (to.ssBounds != null && from.ssBounds != null) { // Instead of moving the small clock the full distance, we compute the distance // smartspace will move. We then scale this to match the duration of this animation // so that the small clock moves at the same speed as smartspace. val ssTranslation = abs((toSSBounds.top - fromSSBounds.top) * smallClockMoveScale).toInt() fromBounds.top = toBounds.top - ssTranslation fromBounds.bottom = toBounds.bottom - ssTranslation abs((to.ssBounds!!.top - from.ssBounds!!.top) * smallClockMoveScale).toInt() from.bounds.top = to.bounds.top - ssTranslation from.bounds.bottom = to.bounds.bottom - ssTranslation } else { Log.e(TAG, "mutateBounds: smallClock received no smartspace bounds") Log.e(TAG, "initTargets: smallClock received no smartspace bounds") } } } Loading Loading @@ -320,10 +339,9 @@ class ClockSizeTransition( } } // TODO: Might need a mechanism to update this one while in-progress class SmartspaceMoveTransition( val config: IntraBlueprintTransition.Config, viewModel: KeyguardClockViewModel, val viewModel: KeyguardClockViewModel, ) : VisibilityBoundsTransition() { private val isLargeClock = viewModel.isLargeClockVisible.value override val captureSmartspace = false Loading @@ -340,23 +358,23 @@ class ClockSizeTransition( addTarget(R.id.status_view_media_container) } override fun mutateBounds( view: View, fromIsVis: Boolean, toIsVis: Boolean, fromBounds: Rect, toBounds: Rect, fromSSBounds: Rect?, toSSBounds: Rect?, ) { override fun initTargets(from: Target, to: Target) { // If view is changing visibility, hold it in place if (fromIsVis == toIsVis) return if (DEBUG) Log.i(TAG, "Holding position of ${view.id}") if (from.isVisible == to.isVisible) return if (DEBUG) Log.i(TAG, "Holding position of ${to.view.id}") if (fromIsVis) { toBounds.set(fromBounds) if (from.isVisible) { to.bounds.set(from.bounds) } else { fromBounds.set(toBounds) from.bounds.set(to.bounds) } } override fun mutateTargets(from: Target, to: Target) { if (to.view.id == sharedR.id.date_smartspace_view) { to.isVisible = !viewModel.hasCustomWeatherDataDisplay.value to.visibility = if (to.isVisible) View.VISIBLE else View.GONE to.alpha = if (to.isVisible) 1f else 0f } } Loading Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt +104 −86 Original line number Diff line number Diff line Loading @@ -86,15 +86,56 @@ class ClockSizeTransition( transition.values[SMARTSPACE_BOUNDS] = targetSSView.getRect() } open fun mutateBounds( view: View, fromIsVis: Boolean, toIsVis: Boolean, fromBounds: Rect, toBounds: Rect, fromSSBounds: Rect?, toSSBounds: Rect?, ) {} open fun initTargets(from: Target, to: Target) {} open fun mutateTargets(from: Target, to: Target) {} data class Target( var view: View, var visibility: Int, var isVisible: Boolean, var alpha: Float, var bounds: Rect, var ssBounds: Rect?, ) { companion object { fun fromStart(startValues: TransitionValues): Target { var fromVis = startValues.values[PROP_VISIBILITY] as Int var fromIsVis = fromVis == View.VISIBLE var fromAlpha = startValues.values[PROP_ALPHA] as Float // Align starting visibility and alpha if (!fromIsVis) fromAlpha = 0f else if (fromAlpha <= 0f) { fromIsVis = false fromVis = View.INVISIBLE } return Target( view = startValues.view, visibility = fromVis, isVisible = fromIsVis, alpha = fromAlpha, bounds = startValues.values[PROP_BOUNDS] as Rect, ssBounds = startValues.values[SMARTSPACE_BOUNDS] as Rect?, ) } fun fromEnd(endValues: TransitionValues): Target { val toVis = endValues.values[PROP_VISIBILITY] as Int val toIsVis = toVis == View.VISIBLE return Target( view = endValues.view, visibility = toVis, isVisible = toIsVis, alpha = if (toIsVis) 1f else 0f, bounds = endValues.values[PROP_BOUNDS] as Rect, ssBounds = endValues.values[SMARTSPACE_BOUNDS] as Rect?, ) } } } override fun createAnimator( sceenRoot: ViewGroup, Loading @@ -109,72 +150,58 @@ class ClockSizeTransition( return null } var fromVis = startValues.values[PROP_VISIBILITY] as Int var fromIsVis = fromVis == View.VISIBLE var fromAlpha = startValues.values[PROP_ALPHA] as Float val fromBounds = startValues.values[PROP_BOUNDS] as Rect val fromSSBounds = startValues.values[SMARTSPACE_BOUNDS] as Rect? val toView = endValues.view val toVis = endValues.values[PROP_VISIBILITY] as Int val toBounds = endValues.values[PROP_BOUNDS] as Rect val toSSBounds = endValues.values[SMARTSPACE_BOUNDS] as Rect? val toIsVis = toVis == View.VISIBLE val toAlpha = if (toIsVis) 1f else 0f val from = Target.fromStart(startValues) val to = Target.fromEnd(endValues) initTargets(from, to) mutateTargets(from, to) // Align starting visibility and alpha if (!fromIsVis) fromAlpha = 0f else if (fromAlpha <= 0f) { fromIsVis = false fromVis = View.INVISIBLE } mutateBounds(toView, fromIsVis, toIsVis, fromBounds, toBounds, fromSSBounds, toSSBounds) if (fromIsVis == toIsVis && fromBounds.equals(toBounds)) { if (from.isVisible == to.isVisible && from.bounds.equals(to.bounds)) { if (DEBUG) { Log.w( TAG, "Skipping no-op transition: $toView; " + "vis: $fromVis -> $toVis; " + "alpha: $fromAlpha -> $toAlpha; " + "bounds: $fromBounds -> $toBounds; ", "Skipping no-op transition: ${to.view}; " + "vis: ${from.visibility} -> ${to.visibility}; " + "alpha: ${from.alpha} -> ${to.alpha}; " + "bounds: ${from.bounds} -> ${to.bounds}; ", ) } return null } val sendToBack = fromIsVis && !toIsVis val sendToBack = from.isVisible && !to.isVisible fun lerp(start: Int, end: Int, fract: Float): Int = MathUtils.lerp(start.toFloat(), end.toFloat(), fract).toInt() fun computeBounds(fract: Float): Rect = Rect( lerp(fromBounds.left, toBounds.left, fract), lerp(fromBounds.top, toBounds.top, fract), lerp(fromBounds.right, toBounds.right, fract), lerp(fromBounds.bottom, toBounds.bottom, fract), lerp(from.bounds.left, to.bounds.left, fract), lerp(from.bounds.top, to.bounds.top, fract), lerp(from.bounds.right, to.bounds.right, fract), lerp(from.bounds.bottom, to.bounds.bottom, fract), ) fun assignAnimValues(src: String, fract: Float, vis: Int? = null) { mutateTargets(from, to) val bounds = computeBounds(fract) val alpha = MathUtils.lerp(fromAlpha, toAlpha, fract) val alpha = MathUtils.lerp(from.alpha, to.alpha, fract) if (DEBUG) { Log.i( TAG, "$src: $toView; fract=$fract; alpha=$alpha; vis=$vis; bounds=$bounds;", "$src: ${to.view}; fract=$fract; alpha=$alpha; vis=$vis; bounds=$bounds;", ) } toView.setVisibility(vis ?: View.VISIBLE) toView.setAlpha(alpha) toView.setRect(bounds) to.view.setVisibility(vis ?: View.VISIBLE) to.view.setAlpha(alpha) to.view.setRect(bounds) } if (DEBUG) { Log.i( TAG, "transitioning: $toView; " + "vis: $fromVis -> $toVis; " + "alpha: $fromAlpha -> $toAlpha; " + "bounds: $fromBounds -> $toBounds; ", "transitioning: ${to.view}; " + "vis: ${from.visibility} -> ${to.visibility}; " + "alpha: ${from.alpha} -> ${to.alpha}; " + "bounds: ${from.bounds} -> ${to.bounds}; ", ) } Loading @@ -190,11 +217,11 @@ class ClockSizeTransition( this@VisibilityBoundsTransition.addListener( object : TransitionListenerAdapter() { override fun onTransitionStart(t: Transition) { toView.viewTreeObserver.addOnPreDrawListener(predrawCallback) to.view.viewTreeObserver.addOnPreDrawListener(predrawCallback) } override fun onTransitionEnd(t: Transition) { toView.viewTreeObserver.removeOnPreDrawListener(predrawCallback) to.view.viewTreeObserver.removeOnPreDrawListener(predrawCallback) } } ) Loading @@ -202,17 +229,17 @@ class ClockSizeTransition( val listener = object : AnimatorListenerAdapter() { override fun onAnimationStart(anim: Animator) { assignAnimValues("start", 0f, fromVis) assignAnimValues("start", 0f, from.visibility) } override fun onAnimationEnd(anim: Animator) { assignAnimValues("end", 1f, toVis) if (sendToBack) toView.translationZ = 0f assignAnimValues("end", 1f, to.visibility) if (sendToBack) to.view.translationZ = 0f } } anim.addListener(listener) assignAnimValues("init", 0f, fromVis) assignAnimValues("init", 0f, from.visibility) } } Loading Loading @@ -251,31 +278,23 @@ class ClockSizeTransition( } } override fun mutateBounds( view: View, fromIsVis: Boolean, toIsVis: Boolean, fromBounds: Rect, toBounds: Rect, fromSSBounds: Rect?, toSSBounds: Rect?, ) { override fun initTargets(from: Target, to: Target) { // Move normally if clock is not changing visibility if (fromIsVis == toIsVis) return if (from.isVisible == to.isVisible) return fromBounds.set(toBounds) from.bounds.set(to.bounds) if (isLargeClock) { // Large clock shouldn't move; fromBounds already set } else if (toSSBounds != null && fromSSBounds != null) { } else if (to.ssBounds != null && from.ssBounds != null) { // Instead of moving the small clock the full distance, we compute the distance // smartspace will move. We then scale this to match the duration of this animation // so that the small clock moves at the same speed as smartspace. val ssTranslation = abs((toSSBounds.top - fromSSBounds.top) * smallClockMoveScale).toInt() fromBounds.top = toBounds.top - ssTranslation fromBounds.bottom = toBounds.bottom - ssTranslation abs((to.ssBounds!!.top - from.ssBounds!!.top) * smallClockMoveScale).toInt() from.bounds.top = to.bounds.top - ssTranslation from.bounds.bottom = to.bounds.bottom - ssTranslation } else { Log.e(TAG, "mutateBounds: smallClock received no smartspace bounds") Log.e(TAG, "initTargets: smallClock received no smartspace bounds") } } } Loading Loading @@ -320,10 +339,9 @@ class ClockSizeTransition( } } // TODO: Might need a mechanism to update this one while in-progress class SmartspaceMoveTransition( val config: IntraBlueprintTransition.Config, viewModel: KeyguardClockViewModel, val viewModel: KeyguardClockViewModel, ) : VisibilityBoundsTransition() { private val isLargeClock = viewModel.isLargeClockVisible.value override val captureSmartspace = false Loading @@ -340,23 +358,23 @@ class ClockSizeTransition( addTarget(R.id.status_view_media_container) } override fun mutateBounds( view: View, fromIsVis: Boolean, toIsVis: Boolean, fromBounds: Rect, toBounds: Rect, fromSSBounds: Rect?, toSSBounds: Rect?, ) { override fun initTargets(from: Target, to: Target) { // If view is changing visibility, hold it in place if (fromIsVis == toIsVis) return if (DEBUG) Log.i(TAG, "Holding position of ${view.id}") if (from.isVisible == to.isVisible) return if (DEBUG) Log.i(TAG, "Holding position of ${to.view.id}") if (fromIsVis) { toBounds.set(fromBounds) if (from.isVisible) { to.bounds.set(from.bounds) } else { fromBounds.set(toBounds) from.bounds.set(to.bounds) } } override fun mutateTargets(from: Target, to: Target) { if (to.view.id == sharedR.id.date_smartspace_view) { to.isVisible = !viewModel.hasCustomWeatherDataDisplay.value to.visibility = if (to.isVisible) View.VISIBLE else View.GONE to.alpha = if (to.isVisible) 1f else 0f } } Loading