首页 > 解决方案 > 如何在 Kotlin 中保存延迟帖子的状态

问题描述

对于 Android 应用程序,我有一些内容想要延迟显示。因此,我正在使用处理程序。

private lateinit var mHandler: Handler

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    linearLayout.isVisible = false

    mHandler = Handler()
    mHandler.postDelayed({
        linearLayout.isVisible = true 
    }, 1000)
}

如何保存此状态(例如在旋转应用程序的情况下)?是否更好使用SharedPreferences或类似的东西:

override fun onSaveInstanceState(outState: Bundle?) {
    super.onSaveInstanceState(outState)

}

override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    super.onRestoreInstanceState(savedInstanceState)

}

标签: androidkotlinsavestateandroid-savedstate

解决方案


我建议使用较新的ViewModel组件来解决此类问题。ViewModel不会像活动和片段那样在配置更改时被破坏,因此您可以运行您的( Handleror Timer) 而不必担心丢失其状态。

class MainViewModel : ViewModel() {
    private val layoutVisibility: MutableLiveData<Boolean> by lazy {
        MutableLiveData().also {
            delayVisibility()
        }
    }

    private fun delayVisibility() {
        Timer().schedule(1000) {
            layoutVisibility.postValue(true)
        }
    }
}

class MainActivity : AppCompatActivity() {
    private lateinit var model: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        model = ViewModelProviders.of(this)[MainViewModel::class.java]

        linearLayout.isVisible = false

        model.layoutVisibility.observe(this, Observer<Boolean> { visibility ->
            linearLayout.isVisible = visibility == true
        })
    }
}

可以保存处理程序的状态——通过保存开始时间并计算重新创建活动时已经过去了多少时间——但ViewModel架构对我来说似乎更直观。

class MainActivity : AppCompatActivity() {
    private lateinit var startTime: Long

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        linearLayout.isVisible = false

        var elapsedTime: Long = 0L    
        if (savedInstanceState != null) {
            startTime = savedInstanceState.getLong(KEY_START_TIME, System.currentTimeMillis())
            elapsedTime = System.currentTimeMillis() - startTime
        } else {
            startTime = System.currentTimeMillis()
        }

        if (elapsedTime >= 1000) {
            linearLayout.isVisible = true
        } else {
            Handler().postDelayed({
                linearLayout.isVisible = true
            }, 1000 - elapsedTime)
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putLong(KEY_START_TIME, startTime)
    }

    companion object {
        private const val KEY_START_TIME = "start_time"
    }
}

推荐阅读