मैं कई अंशों से LiveData का निरीक्षण कर सकता हूं। क्या मैं फ्लो के साथ ऐसा कर सकता हूं? यदि हाँ तो कैसे?
हाँ। आप इसके साथ emit
और कर सकते हैं collect
। सोचना emit
लाइव डेटा के समान है postValue
और collect
इसके समान है observe
। एक उदाहरण देते हैं।
कोष
// 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()
}
टुकड़ा
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
}
}
}
हम नक्शे और स्विचपाइप का उपयोग करके एक एकल LiveData से कई LiveData कर सकते हैं। क्या किसी एकल स्रोत प्रवाह से कई प्रवाह होने का कोई तरीका है?
प्रवाह बहुत आसान है। आप केवल प्रवाह के अंदर प्रवाह बना सकते हैं। कहते हैं कि आप प्रत्येक मौसम पूर्वानुमान डेटा में डिग्री साइन अप करना चाहते हैं।
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)
}
}
}
फिर # 1 के समान ही Fragment में डेटा एकत्र करें। यहाँ क्या होता है व्यू मॉडल रिपॉजिटरी से डेटा इकट्ठा कर रहा है और टुकड़ा व्यू मॉडल से डेटा इकट्ठा कर रहा है।
MutableLiveData का उपयोग करके मैं चर संदर्भ का उपयोग करके कहीं से भी डेटा अपडेट कर सकता हूं। क्या फ्लो के साथ भी ऐसा करने का कोई तरीका है?
आप प्रवाह के बाहर मूल्य फेंक सकते हैं। किसी भी कलेक्टर के होने पर प्रवाह के अंदर कोड ब्लॉक को निष्पादित किया जाता है। लेकिन आप LiveData से asLiveData एक्सटेंशन का उपयोग करके प्रवाह को लाइव डेटा में बदल सकते हैं।
ViewModel
fun getWeatherForecast(): LiveData<String> {
return forecastRepository
.getWeatherForecastEveryTwoSeconds()
.asLiveData() // Convert flow to live data
}
आपके मामले में आप ऐसा कर सकते हैं
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
}
संपादित करें
उनकी टिप्पणी के लिए @mark का धन्यवाद। getWeatherForecast
फ़ंक्शन के लिए दृश्य मॉडल में एक नया प्रवाह बनाना वास्तव में अनावश्यक है। इसे फिर से लिखा जा सकता है
fun getWeatherForecast(): Flow<String> {
return forecastRepository
.getWeatherForecastEveryTwoSeconds(spendingDetailsRequest)
.map {
it + " °C"
}
}