0

我有一个LazyColumn呈现项目列表的。但是,我现在想获取更多项目以添加到我的惰性列表中。我不想重新渲染已经在 中渲染的项目LazyColumn,我只想添加新项目。

我该怎么做StateFlow?我需要传递一个page字符串来获取下一组项目,但是如何将页面传递给该repository.getContent()方法?

class FeedViewModel(
    private val resources: Resources,
    private val repository: FeedRepository
) : ViewModel() {

// I need to pass a parameter to `repository.getContent()` to get the next block of items

    private val _uiState: StateFlow<UiState> = repository.getContent()
        .map { content ->
            UiState.Ready(content)
        }.catch { cause ->
            UiState.Error(cause.message ?: resources.getString(R.string.error_generic))
        }.stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(stopTimeoutMillis = SUBSCRIBE_TIMEOUT_FOR_CONFIG_CHANGE),
            initialValue = UiState.Loading
        )
    val uiState: StateFlow<UiState>
        get() = _uiState

在我的 UI 中,我有这段代码来观察流程并呈现LazyColumn

    val lifecycleAwareUiStateFlow: Flow<UiState> = remember(viewModel.uiState, lifecycleOwner) {
        viewModel.uiState.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED)
    }

    val uiState: UiState by lifecycleAwareUiStateFlow.collectAsState(initial = UiState.Loading)

@Composable
fun FeedLazyColumn(
    posts: List<Post> = listOf(),
    scrollState: LazyListState
) {

    LazyColumn(
        modifier = Modifier.padding(vertical = 4.dp),
        state = scrollState
    ) {
 
        // how to add more posts???
        items(items = posts) { post ->
            Card(post) 
        }
    }
}

我确实意识到 Compose 有一个分页库,但我正在尝试实现类似的东西,除了用户负责是否加载下一个项目。

这是期望的行为:

4

1 回答 1

0

我能够通过在发布之前将新帖子添加到旧帖子来解决这个问题。有关相关行,请参阅下面的评论。

private val _content = MutableStateFlow<Content>(Content())
    private val _uiState: StateFlow<UiState> = repository.getContent()
        .mapLatest { content ->
            _content.value = _content.value + content // ADDED THIS
            UiState.Ready(_content.value)
        }.catch { cause ->
            UiState.Error(cause.message ?: resources.getString(R.string.error_generic))
        }.stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(stopTimeoutMillis = SUBSCRIBE_TIMEOUT_FOR_CONFIG_CHANGE),
            initialValue = UiState.Loading
        )

private operator fun Content.plus(content: Content): Content = Content(
    posts = this.posts + content.posts,
    youTubeNextPageToken = content.youTubeNextPageToken
)
class YouTubeDataSource(private val apiService: YouTubeApiService) :
    RemoteDataSource<YouTubeResponse> {

    private val nextPageToken = MutableStateFlow<String?>(null)

    fun setNextPageToken(nextPageToken: String) {
        this.nextPageToken.value = nextPageToken
    }

    override fun getContent(): Flow<YouTubeResponse> = flow {
        // retrigger emit when nextPageToken changes
        nextPageToken.collect {
            emit(apiService.getYouTubeSnippets(it))
        }
    }
}
于 2022-02-20T04:25:15.987 回答