在我的 Android 应用中,我从 Room 获取数据并将其显示在地图上。我遇到了这两种获取数据的视图模型方法。
哪一个是更有效且更好的方法?
目前,我正在使用第二种方法获取数据。它工作正常。只是想知道这两者之间有什么区别。
第一种方法:
private val _visibleRegion = MutableStateFlow(defaultVisibleRegion)
private val _zoomLevel = MutableStateFlow(6f)
private val _isFavorite = MutableStateFlow(false)
val mapData: StateFlow<PagingData<MapData>> = combine(
_visibleRegion,
_zoomLevel,
_isFavorite
) { region, zoom, isFav ->
Triple(region, zoom, isFav)
}.flatMapLatest { (region, zoom, isFav) ->
repo.getDataInBoundsPaged(
region.southwest.latitude,
region.northeast.latitude,
region.southwest.longitude,
region.northeast.longitude,
zoom = zoom,
isFav = isFav
)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = PagingData.empty()
)
fun updateVisibleRegion(region: LatLngBounds) {
_visibleRegion.value = region
}
fun updateZoomLevel(zoom: Float) {
_zoomLevel.value = zoom
}
fun toggleFavorite(isFavorite: Boolean) {
_isFavorite.value = isFavorite
}
vs 第二种方法:
private val _mapData = MutableStateFlow<PagingData<MapData>>(PagingData.empty())
val mapData: StateFlow<PagingData<MapData>> = _mapData.asStateFlow()
private val defaultVisibleRegion = LatLngBounds(
LatLng(6.792525080049721, 70.06730787456036),
LatLng(37.411989227903604, 86.94231156259775)
)
init {
fetchMapData()
}
fun fetchMapData(
visibleRegion: LatLngBounds = defaultVisibleRegion,
zoomLevel: Float = 6f,
isFavorite: Boolean = false
) {
viewModelScope.launch {
repo.getDataInBoundsPaged(
visibleRegion.southwest.latitude,
visibleRegion.northeast.latitude,
visibleRegion.southwest.longitude,
visibleRegion.northeast.longitude,
zoom = zoomLevel,
isFav = isFavorite
)
.cachedIn(viewModelScope)
.collect {
_mapData.value = it
}
}
}
您应该避免在视图模型中收集流。如果您仅在 UI 中收集,则 UI 可以根据需要订阅和取消订阅 StateFlow,因此可以在不需要时停止底层流。当您使用 进行收集时,此操作会自动完成
collectAsStateWithLifecycle
。因此您不应该使用第二种方法。
第一种方法看起来不错,您可能还想像第二种方法一样缓存分页数据。三重转换也可以稍微简化一下: