Skip to content

Commit

Permalink
Fix crash with Rotary input and empty visible items (#1848)
Browse files Browse the repository at this point in the history
Bug: b/305901991
  • Loading branch information
Kpeved authored Dec 4, 2023
1 parent 1d915f7 commit 1dcdf49
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal class PickerRotaryScrollAdapter(
*/
override fun averageItemSize(): Float =
scrollableState.scalingLazyListState
.layoutInfo.visibleItemsInfo.first().unadjustedSize.toFloat()
.layoutInfo.visibleItemsInfo.firstOrNull()?.unadjustedSize?.toFloat() ?: 0f

/**
* Current (centred) item index
Expand Down Expand Up @@ -81,7 +81,7 @@ internal class AndroidxPickerRotaryScrollAdapter(
*/
override fun averageItemSize(): Float =
scrollableState.scalingLazyListState
.layoutInfo.visibleItemsInfo.first().unadjustedSize.toFloat()
.layoutInfo.visibleItemsInfo.firstOrNull()?.unadjustedSize?.toFloat() ?: 0f

/**
* Current (centred) item index
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package com.google.android.horologist.composables

import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
Expand All @@ -34,6 +35,9 @@ import com.google.android.horologist.composables.picker.PickerScope
import com.google.android.horologist.composables.picker.PickerState
import com.google.android.horologist.composables.picker.rememberPickerState
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
Expand Down Expand Up @@ -165,6 +169,37 @@ class RotaryInteractionTest {
}
}

@OptIn(ExperimentalTestApi::class)
@Test
fun scrollPicker_receiveRotaryEventsBeforeInitialisation() {
lateinit var pickerState: PickerState
val selectedOption = 5
val numberOfOptions = 15
lateinit var scope: CoroutineScope

// Disable clock so that we'll be able to send events before composition finishes
rule.mainClock.autoAdvance = false

rule.setContent {
pickerState = rememberPickerState(
initialNumberOfOptions = numberOfOptions,
initiallySelectedOption = selectedOption,
repeatItems = true,
)
defaultPickerWithRotaryAccumulator(pickerState)
scope = rememberCoroutineScope()
}

scope.launch {
focusRequester.requestFocus()
async {
rule.onNodeWithTag(TEST_TAG).performRotaryScrollInput {
rotateToScrollVertically(50.0f)
}
}
}
}

@Composable
private fun pickerOption(): (@Composable PickerScope.(optionIndex: Int, pickerSelected: Boolean) -> Unit) =
{ value: Int, pickerSelected: Boolean ->
Expand Down

0 comments on commit 1dcdf49

Please sign in to comment.