如何在Android Studio开发的应用中遮盖数据加载延迟 保持启动页显示
解决方案:保持启动页显示直到数据加载完成
你可以通过增加全屏启动页覆盖层的方式实现需求,等所有数据加载完成后再隐藏覆盖层即可,具体实现步骤如下:
步骤1:修改主布局增加启动页覆盖层
调整你的main_activity.xml,在外层套一层FrameLayout用来放启动页,启动页默认悬浮在所有内容上层:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 原有NestedScrollView的所有内容完全保留不变 --> <androidx.core.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_gradient" android:fitsSystemWindows="true"> <!-- 原有布局的所有子控件全部保留 --> </androidx.core.widget.NestedScrollView> <!-- 新增启动页覆盖层,背景替换为你自己的启动页素材 --> <View android:id="@+id/splash_screen" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/你的启动页背景图" /> </FrameLayout>
步骤2:修改数据加载逻辑,加载完成后隐藏启动页
你当前布局共有4个电影分类列表,对应4个接口请求,你需要统计所有接口都加载完成后再隐藏启动页:
- 首先在MainActivity中定义请求计数变量:
// 你需要请求的接口总数量,当前为4个:热门、高分、即将上映、正在上映 private val totalRequestCount = 4 private var finishedRequestCount = 0
- 增加加载完成校验方法:
private fun checkAllLoadFinished() { finishedRequestCount++ // 所有接口都请求完成后隐藏启动页 if (finishedRequestCount == totalRequestCount) { val splashView = findViewById<View>(R.id.splash_screen) // 加300毫秒淡出动画,过渡更自然 splashView.animate() .alpha(0f) .setDuration(300) .setListener(object : Animator.AnimatorListener { override fun onAnimationEnd(animation: Animator?) { splashView.visibility = View.GONE } override fun onAnimationStart(animation: Animator?) = Unit override fun onAnimationCancel(animation: Animator?) = Unit override fun onAnimationRepeat(animation: Animator?) = Unit }) } }
- 在每个接口请求的
onSuccess回调中调用上述方法,比如你贴出的热门电影请求,修改如下:
api.getPopularMovies(page = page) .enqueue(object : Callback<GetMoviesResponse> { override fun onResponse( call: Call<GetMoviesResponse>, response: Response<GetMoviesResponse>, ) { if (response.isSuccessful) { val responseBody = response.body() if (responseBody != null) { onSuccess.invoke(responseBody.movies) // 新增:当前接口请求成功,计入完成数 checkAllLoadFinished() } else { onError.invoke() } } else { onError.invoke() } } override fun onFailure(call: Call<GetMoviesResponse>, t: Throwable) { onError.invoke() } })
其余3个分类的接口请求,都在对应的onSuccess回调里调用checkAllLoadFinished()即可。
额外优化建议
- 可以给Glide加载增加占位图,就算启动页隐藏后图片还在加载,也不会出现空白卡片:修改Adapter的bind方法,Glide加载代码增加
placeholder(R.drawable.你的占位图)参数即可。 - 建议在
onError回调里增加重试逻辑,不要一直停留在启动页,可以弹出Toast提示请求失败,同时增加重试按钮让用户手动触发重新请求。
内容的提问来源于stack exchange,提问作者Shaurya Goyal
相关产品推荐
相关产品推荐

