【问题标题】:kotlin Flow And Emitkotlin 流和发射
【发布时间】:2021-12-30 08:49:06
【问题描述】:

我正在尝试使用 kotlin liveData 并将一些数据发送到我的 viewModel 并在我的片段中将其用作 viewLifecycleOwner。

1-我有一个名为 OrderBasket 的 Singleton 类,它有一个获取字符串的方法

  public String getMyText() {
        if (myText == null || TextUtils.isEmpty(myText))
            return "Nothing to Show";
        return myText;
    }

2-我有一个具有功能的存储库

//这就是我的问题!!!!!!

 val myText: Flow<String> = flow {
    while (true) {
        val textResult = OrderBasket.getInstance().myText
        emit(textResult)
    }

}

3- 我的视图模型是

val myText: LiveData<String> = repository.myText.asLiveData()

最后我的片段 4- 片段

 basketViewModel.myText.observe(viewLifecycleOwner) { text ->
        text.let {

            binding.textHome.setText(text)
        }

问题是我想要做喜欢的房间。 仅在 My Singleton Class 上的数据更改后才自动发出数据,例如 Room 更改数据库上的数据后

我知道我的问题在哪里,但我不知道解决方案!

其实我想在房间里做这样的事情

fun <T> createFlow(query: Query, tables: List<Tables>): Flow<T> = flow {
val changeTracker = tableChangeTracker(tables)

while(true) {
    emit(suspendQuery(query))
    changeTracker.suspendUntilChanged()
}

}

【问题讨论】:

  • 如何更改OrderBasket.myText 的值?您不能像那样观察字符串字段。当此字段更改其值时,您需要触发某种事件。例如,您可以在此字段的 setter 中执行此操作(如果它是由 setter 设置的)。
  • 我的单身人士中有一个二传手

标签: android kotlin kotlin-flow


【解决方案1】:

您可以尝试在您的OrderBasket 类中使用MutableSharedFlow 来获得热数据流。它看起来像这样:

// In OrderBasket class
private val textFlow = MutableSharedFlow<String>() 
val myText(): Flow<String> = textFlow

var myText: String? = "Nothing to Show"
    set(value) {
        val v = if (value == null || TextUtils.isEmpty(value)) "Nothing to Show"
                else value
        field = v
        textFlow.tryEmit(v)
    }

// In Repository
val myText: Flow<String> = OrderBasket.getInstance().myText

// ViewModel and Fragment are the same

【讨论】:

    【解决方案2】:

    我们无法轻易观察到对常规 String 字段 (OrderBasket.myText) 的更改。我们必须以某种方式拦截此值的突变并发送某种事件/通知它已更改。

    假设myText 是通过setter 改变的,这是触发事件的好地方。我们可以使用带有回调的经典方法进行通知,但是您已经使用了流,所以我建议在这里也使用流。从 Java 中使用有点棘手,但没什么难的:

    public class OrderBasket {
        private final MutableStateFlow<String> myTextFlow = StateFlowKt.MutableStateFlow(null);
    
        public StateFlow<String> getMyTextFlow() {
            return FlowKt.asStateFlow(myTextFlow);
        }
    
        public String getMyText() {
            String myText = myTextFlow.getValue();
            if (myText == null || TextUtils.isEmpty(myText))
                return "Nothing to Show";
            return myText;
        }
    
        public void setMyText(String myText) {
            myTextFlow.setValue(myText);
        }
    }
    

    然后你可以在仓库中使用OrderBasket.myTextFlow

    val myText: Flow<String> get() = OrderBasket.getInstance().myTextFlow
    

    【讨论】:

      猜你喜欢
      • 2022-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-24
      • 2011-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多