我正在 Kotlin 中使用
Flow
和 MutateStates
。我的 Data
中有一个 viewModel
列表,对应于几个不同的片段。根据我之前的 SO 问题,仅更新了 MutableStateFlow 中的必要组件AppViewModel
class AppViewModel : ViewModel() {
var dataList: MutableStateFlow<List<DeviceData>> = MutableStateFlow(listOf());
fun getDataForFragment(index: Int): Flow<DeviceData> =
dataList.map { it[index] }.distinctUntilChanged()
fun updateStateFlow(index: Int, data: DeviceData) {
Log.d("stateFlow", "updateStateFlow")
dataList.value = dataList.value.toMutableList().apply {
this[index] = data
}
Log.d("stateFlow", dataList.value.get(index).toString())
}
fun addStateFlow() {
var deviceData_ = DeviceData()
dataList.value = dataList.value.toMutableList().apply {
this.add(deviceData_)
}
}
}
DeviceFragment
class DeviceFragment : Fragment() {
private val viewModel: AppViewModel by activityViewModels()
private var _binding: FragmentDeviceBinding? = null
private val binding get() = _binding!!
private var index: Int? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentDeviceBinding.inflate(inflater)
val bundle = this.arguments
index = bundle!!.getInt("index", 0)
return binding.root
}
@RequiresApi(Build.VERSION_CODES.O)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.viewModelScope.launch {
observers()
}
}
private fun observers() {
lifecycleScope.launchWhenResumed {
index?.let {
viewModel.getDataForFragment(it).collect {
binding.circularProgressView.setProgress(it.progress)
binding.apply {
...
}
}
}
val THRESHOLD = 51.0f
index?.let { it ->
viewModel.getDataForFragment(it).debounce(500)?.collect {
val value = it.probability;
if (value != 0.0F) { //avoid invoking at start of app
if (value > THRESHOLD) {
Log.d("stateFlow", "SENSOR DETECTED")
sensorDetected()
}
}
}
}
}
}
private suspend fun sensorDetected() {
if (index?.let { viewModel.getDataForFragment(it).first().detectCount } == 0) {
Log.d("stateFlow", "sensor invoked")
updateDetectorUI()
}
}
private suspend fun updateDetectorUI() {
when (index?.let { viewModel.getDataForFragment(it).first().detectCount }) {
0 -> {
binding.circularProgressView.setProgress(100f)
changeTintColors(R.color.tint_green)
}
1 -> {
changeTintColors(R.color.tint_purple)
}
2 -> changeTintColors(R.color.tint_purple)
3 -> changeTintColors(R.color.tint_red)
else -> {
binding.circularProgressView.setProgress(100f)
changeTintColors(R.color.tint_green)
}
}
}
override fun onDestroy() {
super.onDestroy()
_binding = null
}
}
当我运行我的应用程序时,我会在 updateStateFlow 中获取包含正确数据的日志。然而,尽管这样做有意义(这些值通过了代码中的条件),但没有显示来自
DeviceFragment
的日志。
更新:我更新流程的方式似乎有问题,但我不知道出了什么问题:/
我不知道这是否有帮助,说实话,我不是流和状态方面的专家,但我通常在视图模型中做这样的状态流事情:
private val _someValue = MutableSateFlow(listof(failedTimeTravelAttempts))
val someValue = _someValue.asStateFlow()
fun updateSomeValue(input: List<TimeTravelStuff>) {
_someValue.value = input
}
当我需要使用这个值并更新它时,说它包含在视图模型中,我会这样使用它:
// collectAsState() may be what you need to use?
val mSomeValue = mViewModel.someValue.collectAsState()
// then when I need it
mSomeValue.value
还有更新,我可以想象你知道这一点,但对于那些不知道这是怎么回事的人来说:
val mNewList = listOf(secretsToTimeTravel)
mViewModel.updateSomeValue(mNewList)