LiveData'yı birden fazla parçadan gözlemleyebilirim. Flow ile yapabilir miyim? Cevabınız evet ise nasıl?
Evet. Bunu emit
ve ile yapabilirsiniz collect
. Düşünmek emit
canlı verilere benzer postValue
ve collect
benzerdir observe
. Bir örnek verelim.
depo
// I just faked the weather forecast
val weatherForecast = listOf("10", "12", "9")
// This function returns flow of forecast data
// Whenever the data is fetched, it is emitted so that
// collector can collect (if there is any)
fun getWeatherForecastEveryTwoSeconds(): Flow<String> = flow {
for (i in weatherForecast) {
delay(2000)
emit(i)
}
}
ViewModel
fun getWeatherForecast(): Flow<String> {
return forecastRepository.getWeatherForecastEveryTwoSeconds()
}
fragman
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// Collect is suspend function. So you have to call it from a
// coroutine scope. You can create a new coroutine or just use
// lifecycleScope
// https://developer.android.com/topic/libraries/architecture/coroutines
lifecycleScope.launch {
viewModel.getWeatherForecastEveryTwoSeconds().collect {
// Use the weather forecast data
// This will be called 3 times since we have 3
// weather forecast data
}
}
}
Map & switchMap kullanarak tek bir LiveData öğesinden birden fazla LiveData alabiliriz. Tek bir Kaynak Akışından birden fazla Akış almanın herhangi bir yolu var mı?
Akış çok kullanışlıdır. Sadece akış içinde akış oluşturabilirsiniz. Hava tahmini verilerinin her birine derece işareti eklemek istediğinizi varsayalım.
ViewModel
fun getWeatherForecast(): Flow<String> {
return flow {
forecastRepository
.getWeatherForecastEveryTwoSeconds(spendingDetailsRequest)
.map {
it + " °C"
}
.collect {
// This will send "10 °C", "12 °C" and "9 °C" respectively
emit(it)
}
}
}
Ardından Fragman'daki verileri # 1 ile aynı şekilde toplayın. Burada olan, görünüm modelinin depodan veri toplaması ve fragman, görünüm modelinden veri toplamasıdır.
MutableLiveData kullanarak değişken başvurusunu kullanarak verileri her yerden güncelleyebilirim. Flow ile aynı şeyi yapmanın bir yolu var mı?
Akış dışında değer veremezsiniz. Akış içindeki kod bloğu yalnızca herhangi bir toplayıcı olduğunda yürütülür. Ancak LiveData'dan asLiveData uzantısını kullanarak akışı canlı verilere dönüştürebilirsiniz.
ViewModel
fun getWeatherForecast(): LiveData<String> {
return forecastRepository
.getWeatherForecastEveryTwoSeconds()
.asLiveData() // Convert flow to live data
}
Sizin durumunuzda bunu yapabilirsiniz
private fun getSharedPrefFlow() = callbackFlow {
val sharedPref = context?.getSharedPreferences("SHARED_PREF_NAME", MODE_PRIVATE)
sharedPref?.all?.forEach {
offer(it)
}
}
getSharedPrefFlow().collect {
val key = it.key
val value = it.value
}
Düzenle
@Mark'a yaptığı yorum için teşekkürler. Görünüm modelinde getWeatherForecast
işlev için yeni bir akış oluşturmak aslında gereksizdir. Olarak yeniden yazılabilir
fun getWeatherForecast(): Flow<String> {
return forecastRepository
.getWeatherForecastEveryTwoSeconds(spendingDetailsRequest)
.map {
it + " °C"
}
}