点击按钮发起API调用后,第二次点击ProgressBar进度条不显示
问题原因及解决方案
核心问题分析
你的代码存在两个关键问题,导致二次点击时ProgressBar不显示:
重复注册LiveData Observer + LiveData粘性特性
每次点击按钮都会创建新的协程,并在协程内部注册新的ApiResponseObserver。LiveData的粘性特性会让新注册的Observer立刻收到之前缓存的响应结果,导致你刚把ProgressBar设为VISIBLE,就被Observer回调立刻设为INVISIBLE,视觉上看不到ProgressBar。Observer注册时机错误
Observer不应该放在协程内部注册,协程是异步执行逻辑,重复注册会导致多个回调实例,进一步加剧状态混乱。
另外你添加delay后能看到ProgressBar,只是因为延迟了Observer的回调时机,给了ProgressBar短暂的显示窗口,并非根本解决办法。
修复步骤
1. 统一注册Observer,只执行一次
在Fragment的onViewCreated或Activity的onCreate中注册Observer,避免重复注册:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 仅注册一次Observer,处理所有API响应 TestVM.ApiResponse.observe(viewLifecycleOwner) { apiResult -> // 不管成功失败,先隐藏ProgressBar myBinding.TestProgressBar.visibility = View.INVISIBLE when (apiResult) { is TestWrapper.Success -> { myBinding.MyTextView.text = String.format( getString(R.string.testString), apiResult.data // 替换为你的实际数据字段 ) } is TestWrapper.Error -> { // 可选:处理错误,比如显示错误提示 } } } }
2. 简化按钮点击逻辑,直接启动协程发起请求
去掉TestJob的自定义getter逻辑,每次点击按钮直接启动新协程,同时确保传入最新的用户输入数据给ViewModel:
myBinding.apiCall.setOnClickListener { val userInput = myBinding.editText.text.toString().trim() // 先执行数据有效性验证 if (userInput.isNotEmpty()) { // 替换为你的实际验证规则 myBinding.TestProgressBar.visibility = View.VISIBLE // 启动协程发起API请求 viewLifecycleOwner.lifecycleScope.launch { TestVM.makeApiCall(userInput) // 传入最新输入数据 } } }
3. 修正ViewModel的API调用逻辑
确保ViewModel每次接收新的输入数据,并更新LiveData:
class TestVM : ViewModel() { private val _apiResponse = MutableLiveData<TestWrapper>() val ApiResponse: LiveData<TestWrapper> = _apiResponse // 接收用户输入数据,发起API请求 suspend fun makeApiCall(inputData: String) { try { // 实际API请求逻辑,比如用Retrofit val response = yourApiService.fetchData(inputData) _apiResponse.postValue(TestWrapper.Success(response)) } catch (e: Exception) { _apiResponse.postValue(TestWrapper.Error(e.message ?: "请求失败")) } } }
额外注意事项
- 避免复用已完成的Job:Job一旦执行完毕就进入Completed状态,无法再次启动,所以每次请求都应该创建新的协程。
- 数据验证要放在UI线程:确保点击按钮时先在主线程完成数据有效性校验,再发起异步请求。
内容的提问来源于stack exchange,提问作者StuckedForeva
相关产品推荐
相关产品推荐

