【问题标题】:Kotlin ViewModel List of StringKotlin ViewModel 字符串列表
【发布时间】:2019-05-03 14:15:05
【问题描述】:

我是 Kotlin 和 ViewModel 使用的新手。 我正在尝试创建一个简单的 ViewModel,它有一个字符串列表。 这个想法是在这个 ViewModel 中更新一个图片路径(字符串)列表。

我的问题是我的 ViewModel 没有更新。它只添加 1 个条目。

class PicturesViewModel : ViewModel() {

    var pictureListLive: MutableLiveData<MutableList<String>> = MutableLiveData()

    var list = ArrayList<String>()

    fun addPictureToList(picture: String) {
        list.add(picture)
        pictureListLive.value = list
    }
}

在我的活动中,我初始化了 viewModel 并像这样观察:

 private fun configureViewModel(){
        this.picturesViewModel = ViewModelProviders.of(this).get(PicturesViewModel::class.java!!)
        this.picturesViewModel.pictureListLive.observe(this, Observer{
            if (it != null) {
                Log.i("Pictures",it.size.toString())
            }
        })
    }

我在 ViewModel 中添加了一个字符串:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_IMAGE_CAPTURE) {
            picturesViewModel.addPictureToList(currentPhotoPath)
            val intentPreview = Intent(this,PreviewActivity::class.java)
            intentPreview.putExtra("Picture",currentPhotoPath)
            startActivity(intentPreview)}

        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CHOOSE_PHOTO){
            this.pictureSelectedPath = data?.data.toString()
            Log.i("Photo",pictureSelectedPath)
        }
    }

ActivityOnResult 来自于对相机拍照后。我想更新 ViewModel 的 String 列表,在拍几张照片后添加图片相机路径。

当我今天这样使用它时,ViewModel 列表的大小仍然为 1。我认为只有最后一个在其中。

感谢您的帮助。

【问题讨论】:

  • 你能把代码传递给你正在初始化视图模型的片段/活动吗?
  • 您的代码没有任何意义。我建议您在开始编写任何代码之前阅读更多关于 Kotlin 和视图模型的使用、LiveData 等的内容。
  • 与问题相关的注释,但这是我对您的代码的建议> 首先您的setPictureList() 不应该有返回值,其次您的getPictureList() 应该返回LiveData 而不是MutableLiveData。您可以在 getPictureList() 中删除此代码 pictureListLive.value = pictureList

标签: android kotlin


【解决方案1】:

这是一个初始化和使用简单 ViewModel 的用例

//in your pictures fragment
private lateinit var picturesViewModel: PicturesViewModel

比你的onCreate

picturesViewModel= ViewModelProviders.of(this).get(PicturesViewModel::class.java)

在你初始化了 viewmodel 之后,你可能会观察到那里发生的数据变化,当然是在初始化的下面:

picturesViewModel.pictureListLive.observe(this, Observer {
            //list changes are handled here 
        })

如果我要重写你的 ViewModelClass 会是这样的:

class PictureViewModel : ViewModel() {

    private var pictureListLive: MutableLiveData<MutableList<String>> = MutableLiveData()


    fun setPictureList(picture: String) {
       val list = ArrayList<String>()
       list.add(picture)
       pictureListLive.value = list 
    }
}

没有必要返回一个列表,因为 MutableLiveData 在发布-订阅逻辑中工作,也就是 Observable Pattern 。

这类似于 EventBus 或 RxJava operators

注意

我需要更多关于 setPictureList 方法的信息,因为这样没有多大意义。或者,也许您想将其称为其他地方或 idk 。

【讨论】:

  • 非常感谢您的回答。 setPictureList 函数是通过向 ViewModel 添加一个新的来更新图片路径列表。这里的问题是列表位于 setPictureList 内,因此当添加新图片字符串时,PictureListLive 将只有一个条目。这应该称为 addPictureList 以便更好地理解。
  • 我已将您的方法设置为我的应用程序。我想在另一个活动中使用 ViewModel。在回收站视图中滑动图片路径。我想我有一些问题。 ViewModel 似乎是空的。其他活动没有更新。
  • 请用您的问题更新问题。我会更新答案。也请告诉我
  • 那是因为 ViewModel 和 activity/fragment 有一个生命周期。当您打开相机活动而不是重新打开列表所在的片段时,数组列表会再次初始化var list = ArrayList&lt;String&gt;()
  • 在这种情况下如何避免新的初始化?
【解决方案2】:

2021 年 4 月 10 日在 Android Studio 4.1.3 Kotlin 1.4.32 compileSdkVersion 30.0.3 可能的解决方案:

dependencies {
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
implementation "androidx.fragment:fragment-ktx:1.3.2"
}

AppCompatActivity 中的代码:创建 ViewModel:

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.LifecycleOwner

class MainActivity : AppCompatActivity() {
private val picturesViewModel: PicturesViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    picturesViewModel.pictureListLive.observe(this, {
       it?.let { Log.i("Pictures", "size =  ${it.size} ${if (it.size>0) it[it.size-1] 
       else "empty"}") }
    })
}

调用应用Camera并返回结果

private var resultLauncher = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
    // There are no request codes
    val data: Intent? = result.data
    val path = result?.data?.getStringExtra(PATH) ?:"sssss"
    picturesViewModel.addPictureToList(path)
  }
}

fun onClick(view: View) {
    val questionIntent = Intent(this, Camera::class.java)
    // new call for startActivityForResult:
    resultLauncher.launch(questionIntent)    }
 }

PicturesViewModel.kt:

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class PicturesViewModel : ViewModel() {

var pictureListLive: MutableLiveData<MutableList<String>> =
    MutableLiveData(mutableListOf())

    fun addPictureToList(picture: String) {
     pictureListLive.value?.add(picture)
     // so that the observer can see that the list has changed
     pictureListLive.value = pictureListLive.value
    }
  }

结果:

2021-04-10 com.example.kotlinviewmodellistofstring I/Pictures: size =  0 empty
2021-04-10 com.example.kotlinviewmodellistofstring I/Pictures: size =  1 123Path
2021-04-10 com.example.kotlinviewmodellistofstring I/Pictures: size =  2 234Path
2021-04-10 com.example.kotlinviewmodellistofstring I/Pictures: size =  3 Path345
2021-04-10 com.example.kotlinviewmodellistofstring I/Pictures: size =  4 Pa456th
2021-04-10 com.example.kotlinviewmodellistofstring I/Pictures: size =  5 Pa567th
2021-04-10 com.example.kotlinviewmodellistofstring I/Pictures: size =  6 Path678
2021-04-10 com.example.kotlinviewmodellistofstring I/Pictures: size =  7 cam123456

【讨论】:

    猜你喜欢
    • 2018-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多