如何将LiveData转换为2个liveData?

时间:2019-07-23 08:11:02

标签: android android-livedata android-viewmodel mutablelivedata

我有configLiveData:LiveData<Response<ConfigFile>>,响应为

sealed class Response<out T> {
  data class Success<out T>(val data: T) : Response<T>()
  data class Failure<out T>(val message: String) : Response<T>()
}

现在在ViewModel中,我想将configLiveData转换为两个不同的 LiveDatas 1。LiveData<ConfigFile>和2。LiveData<String>,由于转换,其中之一将为空。 但我想乘LiveData<Response<ConfigFile>>乘机,而不要乘LiveData<ConfigFile>

 override suspend fun fetchConfigFile(): Response<ConfigFile> {
    return suspendCoroutine { cont ->
      EnigmaRiverContext.getHttpHandler().doHttp(AppConstants.getPath().append("config/appConfig.json").toURL(),
          JsonHttpCall("GET"), object : JsonReaderResponseHandler() {
        override fun onSuccess(jsonReader: JsonReader) {
          try {
            val successObject = ApiConfigFile(jsonReader)
            cont.resume(Response.Success(successObject.toPresenterModel()))
          } catch (e: IOException) {
            cont.resume(Response.Failure(e.message))
          } catch (e: Exception) {
            cont.resume(Response.Failure(e.message ))
          }
        }

        override fun onError(error: Error?) {
          cont.resume(Response.Failure("error.message"))
        }
      })
    }
  }

It is how my Repository looks like 

  private fun fetchConfig() {
    uiScope.launch {
      when (val result = homeRepository.fetchConfigFile()) {
        is Response.Success<ConfigFile> -> {
          postValue(Response.Success(result.data))
        }
        is Response.Failure -> postValue(Response.Failure(result.message))
      }
    }
  }


class ConfigFileLiveData @Inject constructor(val homeRepository: IHomeRepository) : LiveData<Response<ConfigFile>>() {
  private val liveDataJob = Job()
  private val uiScope = CoroutineScope(Dispatchers.Main + liveDataJob)

  override fun onActive() {
    fetchConfig()
  }

  private fun fetchConfig() {
    viewModelScope.launch {
      when (val result = homeRepository.fetchConfigFile()) {
        is Response.Success<ConfigFile> -> {
          postValue(Response.Success(result.data))
        }
        is Response.Failure -> postValue(Response.Failure(result.message))
      }
    }
  }
}

I have `ConfigFileLiveData` which is singleton and I want to use this liveData in other viewModels as I need to fetch config once and use it in different ViewModels


class ConfigFileLiveData @Inject constructor(val homeRepository: IHomeRepository) : LiveData<Response<ConfigFile>>() {

  override fun onActive() {
    fetchConfig()
  }

  private fun fetchConfig() {
    viewModelScope.launch {
      when (val result = homeRepository.fetchConfigFile()) {
        is Response.Success<ConfigFile> -> {
          postValue(Response.Success(result.data))
        }
        is Response.Failure -> postValue(Response.Failure(result.message))
      }
    }
  }
}

1 个答案:

答案 0 :(得分:0)

在Viewmodel中定义两个LiveData变量。

private var configLiveData = MutableLiveData<ConfigFile>()
private var stringLiveData = MutableLiveData<String>()

修改此方法

  private fun fetchConfig() {
        uiScope.launch {
          when (val result = homeRepository.fetchConfigFile()) {
            is Response.Success<ConfigFile> -> {
              configLiveData.value = Response.Success(result.data)
            }
            is Response.Failure -> {
              stringLiveData.value = Response.Failure(result.message)
             }
          }
        }
      }