【问题标题】:viewModel in Kotlin AndroidKotlin Android 中的 viewModel
【发布时间】:2018-07-29 00:46:03
【问题描述】:

我正在尝试了解使用 kotlin for android 的视图模型,但遇到了一些困难。我有一个非常简单的虚拟应用程序,它允许用户增加一个数字,然后将该数字发送到第二个屏幕。然后第二个屏幕将显示一个介于 0 和发送的数字之间的随机数。

这就是问题所在。

我了解如何使用意图将数据从第一页发送到第二页,并且我知道如何在第二页中制作视图模型。但是,如果我发送意图然后将视图模型设置为等于设置的意图,它就无法正常工作。旋转屏幕会导致 Intent 被重新发送,并且 viewmodel 不会保持数据的状态(数字重新随机化)。

理想情况下,我希望能够只更新 viewModel 类而不是发送意图,但是该类的实例是在创建第二个页面时创建的,所以这不起作用。

有什么想法吗?

基于 google codelabs“构建我的第一个 android 应用”教程。

这是我的代码;第一页:

package com.example.patientplatypus.babbysfirstandroidapp

import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.view.View
import android.view.Window
import android.view.WindowManager
import android.widget.Toast

import kotlinx.android.synthetic.main.activity_main.textView
import org.jetbrains.anko.db.PRIMARY_KEY
import org.jetbrains.anko.db.UNIQUE
import org.jetbrains.anko.db.createTable
import android.database.sqlite.SQLiteDatabase
import android.support.v4.content.ContextCompat.startActivity
import com.example.patientplatypus.babbysfirstandroidapp.R.id.textView
import org.jetbrains.anko.db.*
import org.jetbrains.anko.indeterminateProgressDialog

class MainActivity : AppCompatActivity() {

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

    fun toastMe(view: View) {
        val myToast = Toast.makeText(this, "Hello Toast!", Toast.LENGTH_SHORT)
        myToast.show()
    }

    fun countMe (view: View) {
        Log.d("insideCountMeCheck", "hey you are inside count me!")
        val countString = textView.text.toString()
        var count: Int = Integer.parseInt(countString)
        count++
        textView.text = count.toString()
    }

    fun randomMe (view: View) {
        val randomIntent = Intent(this, SecondActivity::class.java)
        val countString = textView.text.toString()
        val count = Integer.parseInt(countString)
        randomIntent.putExtra(SecondActivity.TOTAL_COUNT, count.toString())
        startActivity(randomIntent)
    }
}

这是我的代码,第二页:

package com.example.patientplatypus.babbysfirstandroidapp

import android.arch.lifecycle.ViewModel
import android.arch.lifecycle.ViewModelProviders
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.Window
import android.view.WindowManager
import android.widget.Toast
import java.util.*
import kotlinx.android.synthetic.main.activity_second.randomText

class CountViewModel : ViewModel() {
     var TOTAL_COUNT = "total_count"
}

class SecondActivity : AppCompatActivity() {

    lateinit var countModel: CountViewModel

    companion object {
        const val TOTAL_COUNT = "total_count"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        this.setContentView(R.layout.activity_second)
        countModel = ViewModelProviders.of(this).get(CountViewModel::class.java)
        countModel.TOTAL_COUNT = intent.getStringExtra(TOTAL_COUNT)
        displayForRandomNum(countModel.TOTAL_COUNT);
        showRandomNumber()

    }

    fun showRandomNumber() {
        val count = countModel.TOTAL_COUNT.toInt()
        val random = Random()
        var randomInt = 0
        if (count > 0) {
            randomInt = random.nextInt(count + 1)
        }
        Log.d("randomFinal", Integer.toString(randomInt))
        displayForRandomNum(Integer.toString(randomInt))
    }

    fun displayForRandomNum(totalCount: String){
        randomText.text = totalCount
    }
}

【问题讨论】:

  • 我不知道我明白了。我认为viewModel 的重点是我不必为生命周期挂钩而烦恼,因为它不应该在每次活动结束时都销毁数据。你能给我一个非常简单的例子吗?编辑:另外,理想情况下我根本不想使用 getIntent() - 我只想将它完全保存在 viewModel 中。
  • ViewModel 不会在 Activity 之间共享 - 它们仅适用于一个 Activity。

标签: android mvvm kotlin viewmodel


【解决方案1】:

方向更改会导致 Activity 被销毁然后重新创建。这意味着每次旋转都会调用onCreate。最初启动该活动的相同意图仍然可供它使用。所以intent.getStringExtra(TOTAL_COUNT) 会在每次屏幕旋转时从启动活动的意图返回原始值。 ViewModel 将通过轮换保留数据。

您的问题是,您的重写是 ViewModel'sTOTAL_COUNT,每次都具有来自意图的原始值。您可以做的是检查TOTAL_COUNT 值不是"total_count"(意味着它已经根据意图设置),然后再将其设置为onCreate

【讨论】:

  • 我试过这个if(countModel.TOTAL_COUNT == "total_count") { countModel.TOTAL_COUNT = intent.getStringExtra(TOTAL_COUNT) },所有这些原因都是它挂起并且不能正确旋转。不知道我做错了什么。 imgur.com/a/GuG9r
  • 不知道为什么会挂起。我会调试它并逐步检查onCreate,看看什么是慢的。
猜你喜欢
  • 2020-11-18
  • 1970-01-01
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 1970-01-01
  • 2020-02-13
  • 1970-01-01
相关资源
最近更新 更多