Android NumberPicker 小部件在 Jetpack Compose HorizontalPager 中无法正常工作

问题描述 投票:0回答:2

NumberPicker (android.widget.NumberPicker) 放置在 Jetpack Compose HorizontalPager 中时无法正常工作

滚动3页后,中间数字消失,然后返回选择器页面:

发生这种情况,因此寻呼机一次仅组成 3 个屏幕(当前、上一个和下一个)。当我们向上滚动到第三页然后向后滚动时,选择器页面正在被重组,这就是为什么我们可以观察到这样的错误。

我在 Picker 的 AndroidView 可组合项的更新范围中尝试了 invalidate 方法,但没有帮助。

有什么建议如何解决这个问题吗?谢谢!

重现问题的代码:

应用程序的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'

主要活动:

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) {} } })
}

android android-jetpack-compose android-number-picker jetpack-compose-accompanist android-jetpack-compose-pager
2个回答
0
投票

我也遇到了完全相同的问题。 我通过将 Jetpack compose 依赖项更新到版本

1.3.0
解决了这个问题。

您还可以仅添加当前的 Compose BOM(物料清单)并省略 compose 依赖项的版本号,如下所示:

implementation platform('androidx.compose:compose-bom:2022.10.00')
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.material:material"
implementation ...

您可以在此处阅读有关 Compose BOM 的更多信息:https://developer.android.com/jetpack/compose/setup#using-the-bom


0
投票

我有同样的问题,但在 .NET MAUI 中。 我围绕 NumberPicker 创建了一个自定义控件,但显示该控件时所选值不可见。如果用户滚动,该值是可见的。有什么想法吗?

© www.soinside.com 2019 - 2024. All rights reserved.