Simplifies view-binder.

The view-binder no longer has the view-model-like logic to combine the
UI state of the button with the "animateReveal". Instead, the view-model
takes care of it, simplifiyng the view-binder to make it a bit simpler
and move the complexity into the view-model which allows us to test
that.

Bug: 235403546
Test: Unit tests. Manually verified appear animation is still happening.
Change-Id: Ic836b0e1133d69af0726a4d7fcd4553fd532231f
This commit is contained in:
Alejandro Nijamkin
2022-08-12 14:46:21 -07:00
parent 286094a8e3
commit c5b079b7b6
4 changed files with 46 additions and 40 deletions

View File

@@ -95,35 +95,23 @@ object KeyguardBottomAreaViewBinder {
view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
combine(viewModel.startButton, viewModel.animateButtonReveal) {
buttonModel,
animateReveal ->
Pair(buttonModel, animateReveal)
}
.collect { (buttonModel, animateReveal) ->
updateButton(
view = startButton,
viewModel = buttonModel,
animateReveal = animateReveal,
falsingManager = falsingManager,
)
}
viewModel.startButton.collect { buttonModel ->
updateButton(
view = startButton,
viewModel = buttonModel,
falsingManager = falsingManager,
)
}
}
launch {
combine(viewModel.endButton, viewModel.animateButtonReveal) {
buttonModel,
animateReveal ->
Pair(buttonModel, animateReveal)
}
.collect { (buttonModel, animateReveal) ->
updateButton(
view = endButton,
viewModel = buttonModel,
animateReveal = animateReveal,
falsingManager = falsingManager,
)
}
viewModel.endButton.collect { buttonModel ->
updateButton(
view = endButton,
viewModel = buttonModel,
falsingManager = falsingManager,
)
}
}
launch {
@@ -226,7 +214,6 @@ object KeyguardBottomAreaViewBinder {
private fun updateButton(
view: ImageView,
viewModel: KeyguardQuickAffordanceViewModel,
animateReveal: Boolean,
falsingManager: FalsingManager,
) {
if (!viewModel.isVisible) {
@@ -236,7 +223,7 @@ object KeyguardBottomAreaViewBinder {
if (!view.isVisible) {
view.isVisible = true
if (animateReveal) {
if (viewModel.animateReveal) {
view.alpha = 0f
view.translationY = view.height / 2f
view

View File

@@ -34,7 +34,7 @@ class KeyguardBottomAreaViewModel
constructor(
private val keyguardInteractor: KeyguardInteractor,
private val quickAffordanceInteractor: KeyguardQuickAffordanceInteractor,
bottomAreaInteractor: KeyguardBottomAreaInteractor,
private val bottomAreaInteractor: KeyguardBottomAreaInteractor,
private val burnInHelperWrapper: BurnInHelperWrapper,
) {
/** An observable for the view-model of the "start button" quick affordance. */
@@ -43,12 +43,6 @@ constructor(
/** An observable for the view-model of the "end button" quick affordance. */
val endButton: Flow<KeyguardQuickAffordanceViewModel> =
button(KeyguardQuickAffordancePosition.BOTTOM_END)
/**
* An observable for whether the next time a quick action button becomes visible, it should
* animate.
*/
val animateButtonReveal: Flow<Boolean> =
bottomAreaInteractor.animateDozingTransitions.distinctUntilChanged()
/** An observable for whether the overlay container should be visible. */
val isOverlayContainerVisible: Flow<Boolean> =
keyguardInteractor.isDozing.map { !it }.distinctUntilChanged()
@@ -80,18 +74,24 @@ constructor(
private fun button(
position: KeyguardQuickAffordancePosition
): Flow<KeyguardQuickAffordanceViewModel> {
return quickAffordanceInteractor
.quickAffordance(position)
.map { model -> model.toViewModel() }
return combine(
quickAffordanceInteractor.quickAffordance(position),
bottomAreaInteractor.animateDozingTransitions.distinctUntilChanged(),
) { model, animateReveal ->
model.toViewModel(animateReveal)
}
.distinctUntilChanged()
}
private fun KeyguardQuickAffordanceModel.toViewModel(): KeyguardQuickAffordanceViewModel {
private fun KeyguardQuickAffordanceModel.toViewModel(
animateReveal: Boolean,
): KeyguardQuickAffordanceViewModel {
return when (this) {
is KeyguardQuickAffordanceModel.Visible ->
KeyguardQuickAffordanceViewModel(
configKey = configKey,
isVisible = true,
animateReveal = animateReveal,
icon = icon,
contentDescriptionResourceId = contentDescriptionResourceId,
onClicked = { parameters ->

View File

@@ -26,6 +26,8 @@ import kotlin.reflect.KClass
data class KeyguardQuickAffordanceViewModel(
val configKey: KClass<out KeyguardQuickAffordanceConfig>? = null,
val isVisible: Boolean = false,
/** Whether to animate the transition of the quick affordance from invisible to visible. */
val animateReveal: Boolean = false,
val icon: ContainedDrawable = ContainedDrawable.WithResource(0),
@StringRes val contentDescriptionResourceId: Int = 0,
val onClicked: (OnClickedParameters) -> Unit = {},

View File

@@ -41,6 +41,7 @@ import kotlin.reflect.KClass
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.yield
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -196,11 +197,27 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
@Test
fun animateButtonReveal() = runBlockingTest {
repository.setKeyguardShowing(true)
val testConfig =
TestConfig(
isVisible = true,
icon = mock(),
canShowWhileLocked = false,
intent = Intent("action"),
)
setUpQuickAffordanceModel(
position = KeyguardQuickAffordancePosition.BOTTOM_START,
testConfig = testConfig,
)
val values = mutableListOf<Boolean>()
val job = underTest.animateButtonReveal.onEach(values::add).launchIn(this)
val job = underTest.startButton.onEach { values.add(it.animateReveal) }.launchIn(this)
repository.setAnimateDozingTransitions(true)
yield()
repository.setAnimateDozingTransitions(false)
yield()
assertThat(values).isEqualTo(listOf(false, true, false))
job.cancel()