Remy Benza
02/13/2020, 7:21 AMclass MyViewModel : ViewModel() {
private val _items = MutableLiveData<List<Item>>()
val items: LiveData<List<Item>>
get() = _items
init {
viewModelScope.launch {
_items.value = fetchDataFromNetwork()
}
}
val items: LiveData<List<Item>> = liveData {
emit(fetchDataFromNetwork())
}
Vishal Choudhary
02/13/2020, 7:27 AMRemy Benza
02/13/2020, 7:32 AMFaraz
02/13/2020, 8:19 AMemitSource
this acts as a MediatorLiveData.addSource
as Vishal said.
Then something like this should work:
fun getItems(changeSource: () -> LiveData<List<Item>>) =
liveData {
emit(fetchDatafromNetwork())
//change source
emitSource(changeSource())
}
But then this changing of source will be invoked from within livedata scope. So, if you want to change it from outside and want full control you can extend MediatorLiveData and run your coroutine scope inside it.MediatorLiveData
which is also used in building the current flow livedataRemy Benza
02/13/2020, 8:24 AMclass OnboardingGetToKnowViewModel : ViewModel() {
private val _onboardingTags = MutableLiveData<List<OnboardingTag>>()
val onboardingTags: LiveData<List<OnboardingTag>>
get() = _onboardingTags
private var _selectedTags = MutableLiveData<List<OnboardingTag>>()
val selectedTags: LiveData<List<OnboardingTag>>
get() = _selectedTags
fun addTag(tag: OnboardingTag) {
val existingList = _selectedTags.value ?: emptyList()
val newList = existingList + listOf(tag)
_selectedTags.value = newList
//for grid animation purpose change photo index so 1 becomes 3, 3 becomes 5 etc.
val index = _onboardingTags.value!!.indexOf(tag)
val list = _onboardingTags.value!!.toMutableList()
for (i in index until _onboardingTags.value!!.size step 2) {
val nextItem = list.getOrNull(i + 2)
if (nextItem != null) {
list[i] = nextItem
} else {
list.removeAt(i)
}
}
_onboardingTags.value = list
}
fun removeTag(tag: OnboardingTag) {
val existingList = _selectedTags.value ?: emptyList()
val newList = existingList - listOf(tag)
_selectedTags.value = newList
//for grid animation purpose change photo index so it gets added at the top
val oldPhotos = _onboardingTags.value!!
val index = if (oldPhotos.size % 2 == 0) 2 else 3
val list = oldPhotos.toMutableList()
for (i in index until oldPhotos.size step 2) {
list[i] = oldPhotos[i - 2]
}
if (oldPhotos.size > 1) {
list.add(oldPhotos[oldPhotos.size - 2])
list[index - 2] = tag
} else {
list.add(tag)
}
_onboardingTags.value = list
}
val lastItemTagged = Transformations.map(selectedTags) { list ->
list.lastOrNull()
}
val secondLastItemTagged = Transformations.map(selectedTags) { list ->
list.getOrNull(list.lastIndex - 1)
}
val extraItems = Transformations.map(selectedTags) { list ->
list.size - 2
}
init {
viewModelScope.launch {
_onboardingTags.value = Services.followApi.fetchOnboardingTags()
}
}
}
Zach Klippenstein (he/him) [MOD]
02/13/2020, 3:36 PM