【问题标题】:How can I access to LiveData related object outside the observer?如何在观察者之外访问 LiveData 相关对象?
【发布时间】:2020-05-12 03:21:14
【问题描述】:

我正在制作一个使用房间和 Livedata 来存储和显示数据的应用程序,我可以毫无问题地创建和删除单个项目,但我正在努力创建一个更新值的过程。

问题是我需要在观察者之外访问与 LiveData 对象相关的对象以更改对象值并使用视图模型对其进行更新,但是当我尝试使用 LiveData.value 时,我总是在观察者之外得到一个 null和观察者内部的一个有效对象(我使用吐司和零食来展示这一点,如下面的代码所示)。

那么,如何在观察者之外访问或更新与 LiveData 相关的对象?

    if(intent.hasExtra("MEDICINE_ID")){
        title = getString(R.string.editar_medicamento)
        medicamentoActualLive = medicamentoViewModel.getMedicamento(intent.getIntExtra("MEDICINE_ID",-1))
        medicamentoActualLive.observe(this, android.arch.lifecycle.Observer {
            CampoNombreComercial.setText(it!!.nombreMedicamento,TextView.BufferType.EDITABLE)
            CampoNombreGenerico.setText(it!!.nombreGenerico,TextView.BufferType.EDITABLE)
            CampoDosis.setText(it!!.dosis,TextView.BufferType.EDITABLE)
            CampoNota.setText(it!!.nota,TextView.BufferType.EDITABLE)

            val MedicineTypeIndex =  this.resources.getStringArray(R.array.TipoMedicamento).indexOf(it!!.tipo)
            SpinnerTipoMedicamento.setSelection(MedicineTypeIndex)

            MedicamentoIconoTV.setColorFilter(it.color!!)

            mCurrentPhotoPath = it.fotografia!!
            displayPic()

            medicamento = it
            Toast.makeText(this@AnadirMedicamentoActivity,"El valor del medicamento live es: " + medicamento.nombreGenerico, Toast.LENGTH_SHORT).show()
        })

        Snackbar.make(LayoutConstrain,"El valor del medicamento live externo: " + medicamentoActualLive.value?.nombreGenerico, Snackbar.LENGTH_SHORT).show()

    }else{
        title = getString(R.string.AnadirMedicamento)
    }

保存或更新过程是在浮动操作按钮的onClick方法中调用的这个函数中进行的:

private fun saveMedicineToDB(medicamento: Medicamento){
    if(intent.hasExtra("USER_ID")){
        medicamentoViewModel.update(medicamento)

    }else{
        medicamentoViewModel.insert(medicamento)
    }
    setResult(Activity.RESULT_OK)
    finish()
}

【问题讨论】:

  • 你不需要,因为查询是异步加载的。
  • 那么,有没有办法进行查询,保留对象并稍后更改并使用视图模型更新它?

标签: android kotlin android-livedata


【解决方案1】:

我找到了解决这个问题的方法,因为 cmets 说由于异步查询我无法访问 LiveData 对象数据,但我可以从 UI 事件(在这种情况下为 onClick 事件)访问,这是我的解决方案:

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    val establecimiento : Establecimiento

    if(intent.hasExtra("ESTABLISHMENT_ID")){
        establecimiento = establecimientoActualLive.value!!
    }else{
        establecimiento = Establecimiento(0)
        val sharedPref = PreferenceManager.getDefaultSharedPreferences(this@AnadirEstablecimientoActivity)

        val usuarioID = sharedPref.getInt("actualUserID",-1)
        establecimiento.usuarioID = usuarioID

    }
    when (item.itemId) {
        R.id.itemSave -> {
            establecimiento.nombre  = NombreEstablecimientoTV.text.toString()
            establecimiento.tipo = tipoEstablecimiento
            establecimiento.direccion = DireccionEstablecimientoTV.text.toString()
            establecimiento.telefono1 = Telefono1EstablecimientoTV.text.toString()
            establecimiento.telefono2 = Telefono2EstablecimientoTV.text.toString()
            establecimiento.email = EmailEstablecimientoTV.text.toString()
            establecimiento.sitioWeb = SitioWebEstablecimeintoTV.text.toString()
            establecimiento.latitud = latitud
            establecimiento.longitud = longitud


            if(establecimiento.usuarioID != -1){

                saveEstablishmentToDB(establecimiento)
            }

            return true
        }
        android.R.id.home -> {
            onBackPressed()
            return true
        }
    }
    return super.onOptionsItemSelected(item)

}

【讨论】:

    【解决方案2】:

    此代码来自 Livedata.java

    static final Object NOT_SET = new Object();
    

    ...

    public T getValue() {
        Object data = mData;
        if (data != NOT_SET) {
            return (T) data;
        }
        return null;
    }
    

    ....

    /**
    * Creates a LiveData with no value assigned to it.
    */
    public LiveData() {
        mData = NOT_SET;
        mVersion = START_VERSION;
    }
    

    所以如果 Livedata 对象没有被修改,它将返回 null

    【讨论】:

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