SwipeRefreshLayout进度条完成后无法隐藏问题求助
解决SwipeRefreshLayout下拉刷新后进度条持续显示的问题
嗨,这个问题其实很常见——你只是漏掉了在刷新流程完成(不管成功还是失败)后,手动通知SwipeRefreshLayout停止刷新状态!它的进度条不会自动消失,必须调用特定方法来关闭。
核心问题分析
SwipeRefreshLayout的刷新状态完全由开发者控制:调用setRefreshing(true)会启动刷新动画,而只有调用setRefreshing(false)才能让进度条停下来。你的代码里只触发了数据请求,但没有在请求/数据库操作完成后执行这个关键步骤。
具体修改方案
我们可以通过回调接口让UserRepository在数据操作完成后通知MainActivity,从而关闭刷新动画。
第一步:给UserRepository添加回调接口
修改UserRepository.java,新增一个回调接口,并在数据操作的成功/失败回调里通知外部:
// 新增回调接口,用于通知刷新结果 public interface OnUserListLoadedListener { void onSuccess(); void onError(String errorMessage); } public void getUserList(final OnUserListLoadedListener listener){ Retrofit retrofit = RetrofitClient.getInstance(); ApiService apiService = retrofit.create(ApiService.class); Call<List<User>> userList = apiService.getUser(); userList.enqueue(new Callback<List<User>>() { @Override public void onResponse(Call<List<User>> call, final Response<List<User>> response) { Completable.fromAction(new Action() { @Override public void run() throws Exception { if(response.body() != null) { List<User> list = response.body(); for (int i = 0; i < list.size(); i++) { String id = list.get(i).get_id(); String names = list.get(i).getName(); String age = list.get(i).getAge(); User user = new User(id,names,age); userDb.userDao().Insert(user); } } } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new CompletableObserver() { @Override public void onSubscribe(Disposable d) { } @Override public void onComplete() { Toast.makeText(context,"Data inserted",Toast.LENGTH_SHORT).show(); // 通知MainActivity:数据插入成功,可停止刷新 listener.onSuccess(); } @Override public void onError(Throwable e) { Toast.makeText(context,e.getMessage(),Toast.LENGTH_LONG).show(); // 通知MainActivity:数据插入失败 listener.onError(e.getMessage()); } }); } @Override public void onFailure(Call<List<User>> call, Throwable t) { Toast.makeText(context,t.getMessage(),Toast.LENGTH_LONG).show(); // 通知MainActivity:网络请求失败 listener.onError(t.getMessage()); } }); }
第二步:在MainActivity中处理回调,停止刷新
修改MainActivity.java的刷新监听,在回调里调用setRefreshing(false):
refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { userRepository.getUserList(new UserRepository.OnUserListLoadedListener() { @Override public void onSuccess() { // 停止刷新动画 refresh.setRefreshing(false); // 可选:这里可以重新从数据库获取数据,更新RecyclerView的适配器 // 比如:userAdapter.setData(newUserList); userAdapter.notifyDataSetChanged(); } @Override public void onError(String errorMessage) { // 即使请求/插入失败,也要停止刷新,避免进度条一直转 refresh.setRefreshing(false); } }); } });
更贴合MVVM的优化建议
如果想更符合MVVM的解耦思想,推荐使用LiveData代替回调:
- 在
UserRepository中返回LiveData,封装数据请求的状态(成功/失败/加载中) - 在
ViewModel中持有这个LiveData,并处理业务逻辑 - 在
MainActivity中观察ViewModel的LiveData,收到状态更新后停止刷新动画
这种方式能避免回调嵌套,让代码更清晰易维护。
内容的提问来源于stack exchange,提问作者Digvijay Singh Thakur
相关产品推荐
相关产品推荐

