Как установить LazyVerticalGrid с фиксированным количеством GridCells, но сетка не должна занимать все пространство экраAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Как установить LazyVerticalGrid с фиксированным количеством GridCells, но сетка не должна занимать все пространство экра

Сообщение Anonymous »

Я наткнулся на эту статью:
https://proandroiddev.com/loading-initi ... 747c20ce62
В этой статье автор, описывая преимущества и недостатки различных подходов к инициализации данных, приходит к выводу, что лучше всего это делать с помощью StateFlow. Я решил попробовать, учитывая, что использую обертку UiState в качестве общего состояния экрана.

Код: Выделить всё

sealed class UiState {
object Loading : UiState()
data class Error(val code: Int? = null, val message: String? = null) : UiState()
data class Content(val data: T) : UiState()
}
То есть моя реализация до изменений:

Код: Выделить всё

class MyRepo {
fun getMyData(): Flow {
return flow {
delay(1000)
emit(listOf("1", "2"))
}
}
}

class MyViewModel1(repo: MyRepo): ViewModel() {
data class ScreenStateUI(
val data: List = emptyList(),
val title: String = "Title"
)

private val _screenUiState: MutableStateFlow = MutableStateFlow(UiState.Loading)
val screenUiState: StateFlow = _screenUiState.asStateFlow()

init {
viewModelScope.launch {
repo.getMyData()
.map { UiState.Content(ScreenStateUI(data = it)) }
.collectLatest {
if (it is UiState.Content) {
_screenUiState.emit(
UiState.Content(data = it)
)
}
}
}

fun updateTitle(title: String) {
_screenUiState.update {
if (it is UiState.Content) {
it.copy(data = it.data.copy(title = title))
} else {
it
}
}
}
}
Во время инициализации состояние загружается, и пользовательский интерфейс может подписаться на изменения через screenUiState. Это означает, что не возникнет проблем, если вам нужно использовать забавный updateTitle(title: String).
Теперь я изменил реализацию, чтобы удалить инициализацию в блоке инициализации и сделать все так, как как только пользовательский интерфейс подпишется на событие:

Код: Выделить всё

    class MyRepo {
fun getMyData(): Flow {
return flow {
delay(1000)
emit(listOf("1", "2"))
}
}
}

class MyViewModel2(repo: MyRepo): ViewModel() {
data class ScreenStateUI(
val data: List = emptyList(),
val title: String = "Title"
)

val screenUiState: StateFlow by lazy {
repo.getMyData()
.map { UiState.Content(ScreenStateUI(data = it)) }
.onStart { emit(UiState.Loading) }
.catch { emit(UiState.Error(message = it.message)) }
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = UiState.Loading
)
}

fun updateTitle(title: String) {
...
}
}
Итак, кажется, все выглядит нормально, и действительно, пользовательский интерфейс теперь запускает запросы только при подписке. Однако состояние больше не может быть обновлено, и, следовательно, забавный метод updateTitle(title: String) не может обновить заголовок.
Что мне здесь не хватает?

Подробнее здесь: https://stackoverflow.com/questions/792 ... shouldnt-t
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»