如何更新嵌套实时数据内的值?

问题描述 投票:0回答:1

我有一个名为“调查项目”的类,它是另一个名为“调查数据”的类的子类,如下所示。

@Parcelize
data class DataSurvey(
    @field:SerializedName("name")
    val name: String,

    @field:SerializedName("id")
    val id: String,

    @field:SerializedName("items")
    val items: List<SurveyItem>,

    @field:SerializedName("mobile_only")
    val isMobile: Boolean,
) : Parcelable

@Parcelize
data class SurveyItem(
    @field:SerializedName("survey_id")
    val surveyId: String,

    @field:SerializedName("name")
    val name: String,

    @field:SerializedName("survey_type_id")
    val surveyTypeId: Int,

    @field:SerializedName("id")
    val id: String,

    @field:SerializedName("value")
    var valueItem: @RawValue Any? = null,

    @field:SerializedName("options")
    var options: ArrayList<String>? = arrayListOf(),

    var imageUri: Uri? = null,

    var isComplete: @RawValue MutableLiveData<Boolean> = MutableLiveData<Boolean>(false),
) : Parcelable

我还创建了 livedata 和 mediatorlivedata 来观察其他两个 livedata,因为我需要它们在发送到服务器时不为空。

class CheckInViewModel : ViewModel() {
    // LiveData for etCheckInNotes
    val etCheckInNotesLiveData: MutableLiveData<String> = MutableLiveData()

    // Combined LiveData for etCheckInNotes and surveyItem
    val combinedLiveData: MediatorLiveData<CheckInData> = MediatorLiveData()

    val chosenSurvey = MutableLiveData<ArrayList<DataSurvey>>()

    val listImageUri = MutableLiveData<ArrayList<Uri>>().apply {
        value = arrayListOf()
    }

    init {
        combinedLiveData.addSource(chosenSurvey) { surveyItem ->
            val checkInData = CheckInData(
                notes = etCheckInNotesLiveData.value,
                surveyItems = surveyItem,
                imageUri = listImageUri.value ?: arrayListOf(),
            )
            combinedLiveData.value = checkInData
        }

        combinedLiveData.addSource(etCheckInNotesLiveData) { notes ->
            val checkInData = CheckInData(
                notes = notes,
                surveyItems = chosenSurvey.value ?: arrayListOf(),
                imageUri = listImageUri.value ?: arrayListOf(),
            )
            combinedLiveData.value = checkInData
        }

        combinedLiveData.addSource(listImageUri) { imageUri ->
            val checkInData = CheckInData(
                notes = etCheckInNotesLiveData.value,
                surveyItems = chosenSurvey.value ?: arrayListOf(),
                imageUri = imageUri,
            )
            combinedLiveData.value = checkInData
        }
    }

    data class CheckInData(
        val notes: String?,
        val surveyItems: ArrayList<DataSurvey>,
        val imageUri: ArrayList<Uri>,
    )
}

以下是我观察组合的实时数据时

// Observe combinedLiveData
checkInViewModel.combinedLiveData.observe(this) { (etCheckInNotes, surveyData, uriImage) ->
    val allValuesPresent =
        surveyData.all { it.items.all { item -> item.valueItem != null } }

    Log.e(TAG, "allvalues : $allValuesPresent")
    Log.e(TAG, "etcheckinnotes : ${etCheckInNotes.toString()}")
    Log.e(TAG, "etcheckinnotes null or empty ${etCheckInNotes.isNullOrEmpty()}")
    Log.e(TAG, "surveyItem $surveyData")
    Log.e(TAG, "buttonStatus : ${binding.btCheckInSubmit.getButtonEnable()}")
    Log.e(TAG, "uriImage $uriImage")

    if (allValuesPresent && !etCheckInNotes.isNullOrEmpty()) {
        binding.btCheckInSubmit.setButtonEnabled(true)
        binding.btCheckInSubmit.showLoading(false)
    } else {
        binding.btCheckInSubmit.setButtonEnabled(false)
    }
}

但是,当我尝试在 recyclerviewadapter 内更新它们时,当我只输入一个字符时,视图总是会刷新。

binding.tiSurveyItemDesc.addTextChangedListener(object : TextWatcher {
    override fun beforeTextChanged(
        s: CharSequence?,
        start: Int,
        count: Int,
        after: Int,
    ) {
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
//                    Log.e("test", "$s")
        val note = s.toString()
//                    viewModel.updateSurveyItemValueItem(
//                        surveyData.surveyId,
//                        surveyData.id,
//                        note
//                    )
        // Update the valueItem of the survey item and notify observers

        viewModel.viewModelScope.launch {
            viewModel.chosenSurvey.value?.get(outerIndex)?.items?.get(position)?.valueItem =
                note
//                        viewModel.chosenSurvey.value = viewModel.chosenSurvey.value
        }
    }

    override fun afterTextChanged(s: Editable?) {

    }
})

binding.tiSurveyItemDesc.setOnEditorActionListener { v, actionId, event ->
    if (actionId == EditorInfo.IME_ACTION_NEXT) {
        // Hilangkan fokus dari TextInputEditText
        binding.tiSurveyItemDesc.clearFocus()
        viewModel.chosenSurvey.postValue(viewModel.chosenSurvey.value) // Notify observers

        // Opsional: Sembunyikan keyboard
//                    val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
//                    imm.hideSoftInputFromWindow(v.windowToken, 0)

        true // Return true untuk menandakan event sudah ditangani
    } else {
        false
    }
}

我知道这是由post值引起的。但是我如何观察 3 个多个实时数据,在不刷新 UI 的情况下更新一个实时数据中的一个实时数据值?

这是预览:

android kotlin android-livedata mediatorlivedata
1个回答
0
投票

MediatorLiveData 已弃用,您可以尝试其他类似 MediatorLiveData

[LiveData<Integer> liveData1 = ...;
LiveData<Integer> liveData2 = ...;

MediatorLiveData<Integer> liveDataMerger = new MediatorLiveData<>();
liveDataMerger.addSource(liveData1, value -> liveDataMerger.setValue(value));
liveDataMerger.addSource(liveData2, value -> liveDataMerger.setValue(value));][1]
© www.soinside.com 2019 - 2024. All rights reserved.