【问题标题】:Handle screen rotation progress without losing data by using Seekbar - Android Kotlin使用 Seekbar 处理屏幕旋转进度而不丢失数据 - Android Kotlin
【发布时间】:2021-08-14 23:43:48
【问题描述】:

我是 android studio 的新手,我在旋转屏幕时遇到问题,搜索栏进度将重置为 0,我曾尝试使用保存的实例状态但进度仍然重置它,谁能帮助我给我一些解决方案?

我收到此错误 类型不匹配:推断类型是字符串?但需要 Int

谢谢大家。希望你们早日回来

上面是 MainActivity.kt 中的代码

//the bottom one
var no:Int=0
private val SEEKBAR ="seekbar"

//Inside the onCreate
    if (savedInstanceState !=null)       {
        val value = savedInstanceState.getString(SEEKBAR)
        seekbar1.progress=value
        no= value?.toInt() ?:0
    }

//after the onCreate
override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)

val seekbar1 = seekbar1.progress.toString()
outState.putString(SEEKBAR,seekbar1)
}

【问题讨论】:

    标签: android arrays android-studio kotlin android-seekbar


    【解决方案1】:

    您正在将字符串传递给 seekbar 的进度函数。 我们需要传递整数。 所以,只需使用 seekbar_weight.progress = value.toInt()

    查看您的代码后更新:

    在您的代码中,在 setVariable() 函数中,您正在根据用户选择的单位设置一些 UI。

    在执行此操作时,您将搜索栏的进度设置为 0。并且在从 onRestoreInstateState 恢复进度值后调用此函数。恢复后,您将再次从setVariable() 函数将其设置为零。

    因此,您只需从setVariable() 函数中删除 8 行(用于设置搜索栏进度和显示搜索栏进度的文本)。

    所以,您的 setVariable() 函数应该如下所示:

        private fun setVariable() {
        //Set the text of units and the max progress
        spinner_units.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(
                parent: AdapterView<*>?,
                view: View?,
                position: Int,
                id: Long
            ) {
                if (position == 0) {
                    text_weight.text = "Weight (kg)"
                    text_height.text = "Height (cm)"
                    seekbar_weight.max = 450
                    seekbar_height.max = 250
                    number_picker_age.value = 2
                    bmi_meter.speedTo(0F)
                } else if (position == 1) {
                    text_weight.text = "Weight (ibs)"
                    text_height.text = "Height (in)"
                    seekbar_weight.max = 770
                    seekbar_height.max = 80
                    number_picker_age.value = 2
                    bmi_meter.speedTo(0F)
                }
    
            }
            override fun onNothingSelected(parent: AdapterView<*>?) {
            }
        }
    }
    

    更新 2:更新后的要求

    对于您在此处更新的要求,您可以: 带回从setVariable() 方法中删除的那8行。

    在您的strings.xml 文件中,在微调器的字符串数组中添加一项“选择”。

    <string-array name="units">
            <item>Select</item>
            <item>Metric</item>
            <item>Imperial</item>
    </string-array>
    

    MainActivity 中,覆盖onPause() 方法并将微调器设置为位置0。

    override fun onPause() {
        super.onPause()
        spinner_units.setSelection(0)
    }
    

    这应该可以解决您的问题。如果不是,请回复。

    【讨论】:

    • 嗨,我曾尝试添加但无法正常工作,当我旋转相同的值时,值将被重置,还有其他解决方案吗?
    • 我已经更新了我的答案。你只需要用我的代码替换你的 setVariable() 函数。您的问题将得到解决。
    • 嗨,Skafle,我已经将它删除了代码 8 行,它在旋转时不会被重置。但是现在我遇到了另一个问题,那就是当我选择不同的单位时,进度不会被重置。那是其他可以解决旋转问题并选择不同单位将重置搜索栏的方法吗?我也非常感谢你
    • 我第二次更新了我的答案。请检查一下,看看它是否有效。
    • 谢谢,我稍后再试试
    【解决方案2】:

    试试onRestoreInstanceState 怎么样,它只有在onSaveInstanceState 方法中保存某些内容并返回非空时才会触发。

    但是,您需要使用 putInt() 而不是 putString(),因为 SeekBar 的值是 Integer

     override fun onSaveInstanceState(outState: Bundle) {
            super.onSaveInstanceState(outState)
            val seekbar1 = seekBar1.progress
    
            //use putInt() method 
            outState.putInt(SEEKBAR, seekbar1)
        }
    
    
        override fun onRestoreInstanceState(savedInstanceState: Bundle) {
            super.onRestoreInstanceState(savedInstanceState)
    
            //retrieve value using getInt() method
            val value = savedInstanceState.getInt(SEEKBAR)
            seekBar1.progress = value
    
        }
    

    告诉我们进展如何。

    干杯。

    【讨论】:

    • 所以当我在 if 中使用 onRestoreIntanceState 以及如何调用它时,我对此一无所知...可以给我一些指导或想法吗?
    • 您好勇伟,您可以使用onCreate()onRestoreInstanceState()。 onRestoreInstanceState() 的好处是它仅在保存实例时调用,并且 永远不会返回可为空的 savedInstanceState 所以不需要 -if-else 。如果您选择使用onCreate(),那么您需要使用if-else。请尝试告诉我。
    • 嗨,Tonnie,我听不懂,我还是 android studio 的新手,对此感到抱歉,所以现在这个解决方案是我需要使用 onRestoreInstanceState 然后不需要使用 onSaveInstanceState 吗?或者两者我也需要使用它。以及如何声明我刚刚放在onCreate下方但我尝试过的函数,但是当旋转时也会被重置
    • 请参考我上面的代码,你仍然需要覆盖onSaveInstanceState()onCreate()' like I have done. For restoring the value you can either do it inside onCreate()`(就像你之前做的那样)或者选择添加onRestoreInstanceState()' method and move the restore code inside onRestoreInstance() '。
    • 您好,我将代码推送到Github 看看您是否可以访问,非常感谢您额外调试我的代码...
    【解决方案3】:

    已检查您的代码并按照承诺进行了调试。

    问题

    每次旋转手机时都会重新创建您的活动。

    每次都会触发onCreate(),从而调用这行代码。

    setReferences()//Setup Gui Components

    setReferences() 是让一切都被重置并归零的人。

    解决方案

    转到您的清单文件并添加这行代码。

    android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"&gt;

    已为您提供下图...

    这将阻止您的活动在每次轮换时重新创建,setReferences() 只会被调用一次。

    接下来删除onSaveInstanceStateonRestoreInstanceState这两个函数,因为你不再需要它们了。

    【讨论】:

    • 这不是一个劣质的解决方案吗?
    • 您建议的方式可以停止活动的重新创建,但不建议这样做,只能作为最后的手段。 [文档链接] (developer.android.com/guide/topics/resources/…) 您已经提到了 4 项配置更改,但还有其他一些配置更改将导致活动的重新创建。我也浏览了代码,找到了错误的原因并提出了解决方案。
    • 嗨 Tonnie,感谢您帮助调试代码,但我可以说这对我没有多大帮助,这是因为如果我使用 android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"&gt; 时,我的横向布局不同旋转布局将与我的肖像完全一样。在您之前的代码中,使用onSaveInstanceStateonRestoreInstanceState 会很有帮助,并且@skafle 已经调试了该代码并从 set 变量中删除了第 8 行。您是否有任何解决方案,当我选择不同的单位时,进度将重置为 0?
    猜你喜欢
    • 2020-10-23
    • 2011-07-04
    • 2021-11-16
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    相关资源
    最近更新 更多