You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Retrofit中重新发起请求实现下拉刷新获取更新数据?

实现下拉刷新重新获取API数据

核心思路

下拉刷新是用户主动触发的重新请求,不需要依赖OkHttp拦截器(拦截器多用于自动重试失败请求,比如网络波动时)。只需在ViewModel中暴露刷新方法,配合Compose的SwipeRefresh组件即可实现。

步骤1:修改ViewModel,添加刷新方法

把原本私有数据获取方法包装成可外部调用的刷新函数,确保重新请求时能正确更新状态:

@HiltViewModel
class MatchesViewModel @Inject constructor(
    private val matchRepository: MatchRepository
): ViewModel()  {

    val response: MutableState<ApiState> = mutableStateOf(ApiState.Empty)

    init {
        getAllMatches()
    }

    // 暴露给外部调用的刷新方法
    fun refreshMatches() = viewModelScope.launch {
        getAllMatches()
    }

    private fun getAllMatches() = viewModelScope.launch {
        matchRepository.getAllMatches()
            .onStart {
                response.value = ApiState.Loading
            }
            .catch {
                response.value = ApiState.Failure(it)
            }
            .collect {
                response.value = ApiState.Success(it)
            }
    }
}

步骤2:在Compose中添加下拉刷新组件

使用Jetpack Compose自带的SwipeRefresh包裹页面内容,关联刷新状态并触发刷新:

@Composable
fun MainScreen(viewModel: MatchesViewModel = hiltViewModel()){
    // 根据当前状态判断是否处于刷新中
    val isRefreshing = viewModel.response.value is ApiState.Loading
    
    SwipeRefresh(
        state = rememberSwipeRefreshState(isRefreshing = isRefreshing),
        onRefresh = { viewModel.refreshMatches() } // 下拉时触发刷新
    ) {
        when (val result = viewModel.response.value){
            is ApiState.Success -> {
                HomeScreen(matches = result.data.data)
            }
            is ApiState.Loading -> {
                Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                    CircularProgressIndicator()
                }
            }
            is ApiState.Empty -> {
                Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                    Text(text = "暂无数据")
                }
            }
            is ApiState.Failure -> {
                Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                    Text(text = "加载失败:${result.exception.message ?: "未知错误"}")
                }
            }
        }
    }
}

补充说明

  • SwipeRefresh会自动处理下拉时的刷新指示器,无需额外编写动画逻辑。
  • 若需要实现自动重试失败请求(比如网络差时自动重试),才需要用到OkHttp拦截器,可通过OkHttp的RetryInterceptor配置重试次数、重试条件(如HTTP 5xx错误)。

内容的提问来源于stack exchange,提问作者jaskaran singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 09:15:47