我有一个名为“调查项目”的类,它是另一个名为“调查数据”的类的子类,如下所示。
@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 的情况下更新一个实时数据中的一个实时数据值?
这是预览:
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]