状态更改时片段不会更新

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

我正在 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
的日志。

更新:我更新流程的方式似乎有问题,但我不知道出了什么问题:/

android kotlin kotlin-coroutines android-viewmodel
1个回答
0
投票

我不知道这是否有帮助,说实话,我不是流和状态方面的专家,但我通常在视图模型中做这样的状态流事情:

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)
© www.soinside.com 2019 - 2024. All rights reserved.