You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose HorizontalPager中android.widget.NumberPicker异常问题

解决HorizontalPager中NumberPicker返回后中间数字消失的问题

方案1:持久化并恢复选中状态

页面重组时AndroidView会重新初始化NumberPicker,导致状态丢失引发显示异常。通过remember保存选中值,在创建和更新阶段同步状态:

val selectedValue = remember { mutableStateOf(5) } // 初始值按需设置

HorizontalPager(count = 5) { page ->
    if (page == 0) {
        AndroidView(
            factory = { context ->
                NumberPicker(context).apply {
                    minValue = 0
                    maxValue = 10
                    value = selectedValue.value
                    setOnValueChangedListener { _, _, newVal ->
                        selectedValue.value = newVal
                    }
                }
            },
            update = { picker ->
                if (picker.value != selectedValue.value) {
                    picker.value = selectedValue.value
                }
                picker.postInvalidate() // 用postInvalidate确保UI刷新
            }
        )
    } else {
        Text("Page $page")
    }
}

核心是用remember维持选中值的生命周期,让重组后的Picker能恢复到之前的选中状态,避免显示异常。

方案2:增大Pager的预加载页面数

HorizontalPager默认offscreenPageLimit=1,仅保留当前页及前后各一页的状态。如果Picker页面与当前滚动页间隔超过1,就会被销毁重组。增大预加载数可避免该问题:

HorizontalPager(
    count = 5,
    offscreenPageLimit = 3 // 确保Picker页面始终在预加载范围内
) { page ->
    // 页面内容
}

注意:该方法会增加内存占用,适合页面数量较少的场景。

方案3:给AndroidView设置固定Key

通过固定key,让AndroidView在页面重组时复用原有实例,而非重新创建:

AndroidView(
    factory = { context ->
        NumberPicker(context).apply {
            minValue = 0
            maxValue = 10
        }
    },
    key = "fixed_number_picker" // 固定key,避免实例重建
) { picker ->
    picker.value = selectedValue.value
}

建议结合方案1使用,既保证实例复用,又能恢复正确的选中状态。

内容的提问来源于stack exchange,提问作者Merkost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 07:55:23