android - 如何掩盖android Studio中的加载时间延迟?
问题描述
我在 Android Studio 中制作了一个从网站导入数据的应用程序......当我打开应用程序时,要在其中导入数据的卡片视图是空的,并在一段时间后加载。我想知道是否有任何方法可以掩盖它,以便在加载它之前我的启动屏幕一直保持在那里。这是一个显示滞后的视频:
编辑:这是电影适配器:
class MoviesAdapter(
private var movies: MutableList<Movie>,
private val onMovieClick: (movie: Movie) -> Unit,
) : RecyclerView.Adapter<MoviesAdapter.MovieViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.item_movie, parent, false)
return MovieViewHolder(view)
}
override fun getItemCount(): Int = movies.size
override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
holder.bind(movies[position])
}
fun appendMovies(movies: List<Movie>) {
this.movies.addAll(movies)
notifyItemRangeInserted(
this.movies.size,
movies.size - 1
)
}
inner class MovieViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val poster: ImageView = itemView.findViewById(R.id.item_movie_poster)
fun bind(movie: Movie) {
itemView.setOnClickListener { onMovieClick.invoke(movie) }
Glide.with(itemView)
.load("https://image.tmdb.org/t/p/w342${movie.posterPath}")
.transform(CenterCrop())
.into(poster)
}
}
}
我的 main_activity_xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_gradient"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="25dp"
android:layout_marginEnd="16dp"
android:text="@string/discover"
android:textColor="@android:color/white"
android:textSize="45sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/popular"
android:textColor="@android:color/white"
android:textSize="22sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/most_popular_movies" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/popular_movies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/top_rated"
android:textColor="@android:color/white"
android:textSize="22sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/highest_rated_movies" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/top_rated_movies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/upcoming"
android:textColor="@android:color/white"
android:textSize="22sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/stay_updated" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/upcoming_movies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:text="@string/now_playing"
android:textColor="@android:color/white"
android:textSize="22sp"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/now_in_Cinemas" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/now_playing_movies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="10dp"
android:clipToPadding="false"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
API 密钥:
interface Api {
@GET("movie/popular")
fun getPopularMovies(
@Query("api_key") apiKey: String =
"eff7d87eb14cdf1fb273414692d3e3a8",
@Query("page") page: Int,
): Call<GetMoviesResponse>
}
API 加载器:
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)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetMoviesResponse>, t:
Throwable) {
onError.invoke()
}
})
还有什么我应该指定的吗?
解决方案
没有代码很难回答这个问题,但你总是可以使用一个 ViewSwitcher,它在卡片视图的数据准备好之前显示“正在加载”状态,但保留空间,所以 UI 不会跳转,然后有卡片加载数据后显示的视图。
可能是这样的:
sealed class CardData {
object Loading: CardData()
class Info(val items: List<CardInfo>): CardData()
}
fun loadData() {
viewModel.cardData.observe { cardData ->
when(cardData) {
is Loading -> {
binding.switcher.displayedChild = 0
}
is Info -> {
binding.switcher.displayedChild = 1
binding.listOfCards.items = cardData.items
}
}
}
对于您的具体情况:
// display the loading view before making the call
binding.switcher.displayedChild = 0
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)
} else {
onError.invoke()
}
} else {
onError.invoke()
}
}
override fun onFailure(call: Call<GetMoviesResponse>, t:
Throwable) {
onError.invoke()
}
})
// in your onSuccess()
private void onSuccess(List<Movies> movies) {
binding.switcher.displayedChild = 1
listAdapter.items = movies
listAdapter.notifyDatasetChanged()
}
// in your onError()
private void onError() {
binding.switcher.displayedChild = 2 // you can add a third child for errors
}
那么 XML 将类似于(缺少属性):
<ViewSwitcher
android:id="@+id/switcher">
<!-- child 0 - loading state -->
<ProgressBar
android:id="@+id/loader"
/>
<!-- child 1 - movies state -->
<RecyclerView
android:id="@+id/movies"
/>
<!-- child 2 - error state -->
<TextView
android:id="@id/error_text"
/>
</ViewSwitcher>
推荐阅读
- regex - PowerShell 在文件行为中查找和替换正则表达式
- python - Kodi ssh python 脚本 *没有文件或目录*
- pandas - pandas split-apply-combine 与返回原始 DataFrame 的结果
- java - Checkstyle 找不到 suppresss.xml
- python - HackerRank 分类超时问题
- javascript - 转换为 JSON 时,现有的 python3 Ordered Dict 到 JSON 对象没有保持其顺序
- debian - 查看 .deb 存档的内容文件
- python - Python Boxplot 颜色映射
- javascript - 如何访问 HTML 自定义元素中的内容文本?
- webgl - WebGL(Regl)中具有大坐标的网格的视觉伪影