Reputation: 2376
Middle number disappears after scrolling away 3 pages and then return to a picker page:
It happens hence pager keeps composed only 3 screens at time (current, previous and next). When we scroll up to 3rd page and then scroll back, the picker page is being recomposed and that's why we can observe such bug.
I have tried invalidate method in update scope of Picker's AndroidView composable, but it doesn't help.
Any suggestions how to resolve the issue? Thanks!
App's buildSrc:
//ACCOMPANIST
api "com.google.accompanist:accompanist-pager:0.27.0"
api "com.google.accompanist:accompanist-pager-indicators:0.27.0"
//COMPOSE
implementation platform('androidx.compose:compose-bom:2022.10.00')
implementation "androidx.compose.ui:ui"
implementation 'androidx.compose.material:material'
implementation 'androidx.activity:activity-compose:1.6.1'
MainActivity:
import android.os.Bundle
import android.widget.NumberPicker
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.example.composepagerpickerissue.ui.theme.ComposePagerPickerIssueTheme
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.rememberPagerState
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() {
@OptIn(ExperimentalPagerApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposePagerPickerIssueTheme {
val coroutineScope = rememberCoroutineScope()
val pages = listOf(
Page.PickerPage,
Page.EmptyPage,
Page.EmptyPage,
Page.EmptyPage,
Page.PickerPage,
)
val pagerState = rememberPagerState(0)
val onNextPage: () -> Unit = {
coroutineScope.launch { pagerState.animateScrollToPage(page = pagerState.currentPage + 1) }
}
val onPreviousPage: () -> Unit = {
coroutineScope.launch {
pagerState.animateScrollToPage(
page = (pagerState.currentPage - 1).takeIf { it >= 0 } ?: 0
)
}
}
Column {
HorizontalPager(
count = pages.size,
state = pagerState,
modifier = Modifier.weight(1f, true)
) { page ->
pages[page].screen()
}
Row(
modifier = Modifier.padding(16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
OutlinedButton(
modifier = Modifier.weight(1f),
onClick = onPreviousPage
) { Text("Back") }
Button(
modifier = Modifier.weight(1f),
onClick = onNextPage
) { Text("Next") }
}
}
}
}
}
}
@Composable
fun SimpleNumberPicker(
value: Int,
min: Int = 0,
max: Int = Int.MAX_VALUE,
onValueChange: (Int) -> Unit
) {
AndroidView(
modifier = Modifier.fillMaxWidth(),
factory = { context ->
NumberPicker(context).apply {
setOnValueChangedListener { numberPicker, i, i2 ->
onValueChange(i)
}
minValue = min
maxValue = max
this.value = value
}
},
update = {}
)
}
sealed class Page(var screen: @Composable () -> Unit) {
object EmptyPage : Page(
screen = { Box(modifier = Modifier.fillMaxSize()) { Text(text = "Empty screen") } })
object PickerPage : Page(
screen = { Column(modifier = Modifier.fillMaxSize()) { SimpleNumberPicker(150) {} } })
}
Upvotes: 1
Views: 1451
Reputation: 1
I had the exact same problem too.
I solved it by updating the Jetpack compose dependencies to version 1.3.0
.
You can also just add the current Compose BOM (Bill of Materials) and omit the version numbers for the compose dependencies, like this:
implementation platform('androidx.compose:compose-bom:2022.10.00')
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.material:material"
implementation ...
You can read more about the Compose BOM here: https://developer.android.com/jetpack/compose/setup#using-the-bom
Upvotes: 0