android - 使用 GridLayoutManager 在分页库中设置跨度大小
问题描述
GridLayoutManager
当在分页库中LoadState
时,将跨度大小设置为 1 。Loading
我已经尝试过这个解决方案,但它不起作用。
对于复制问题:克隆这个官方 repo 并GridLayoutManager
设置SearchRepositoriesActivity
我的代码在这里
电影列表片段
....
private val adapter = MoviesAdapter()
....
private fun initAdapter() {
val decoration = DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL)
binding.rvMovies.addItemDecoration(decoration)
binding.rvMovies.layoutManager = GridLayoutManager(requireContext(), 2)
binding.rvMovies.isNestedScrollingEnabled = true
binding.rvMovies.adapter = adapter.withLoadStateFooter(
footer = MoviesLoadStateAdapter { adapter.retry() }
)
}
电影适配器
class MoviesAdapter(
) : PagingDataAdapter<Movie, MoviesAdapter.ViewHolder>(MOVIE_COMPARATOR) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = ItemMovieListBinding.inflate(LayoutInflater.from(parent.context))
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val movie = getItem(position)
if (movie != null) {
val viewModel = MovieListItemViewModel(movie)
holder.bind(viewModel)
}
}
inner class ViewHolder(var viewBinding: ItemMovieListBinding) :
RecyclerView.ViewHolder(viewBinding.root) {
fun bind(viewModel: MovieListItemViewModel) {
viewBinding.viewModel = viewModel
}
}
companion object {
private val MOVIE_COMPARATOR = object : DiffUtil.ItemCallback<Movie>() {
override fun areItemsTheSame(oldItem: Movie, newItem: Movie): Boolean =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: Movie, newItem: Movie): Boolean =
oldItem == newItem
}
}
}
MoviesLoadStateAdapter
class MoviesLoadStateAdapter(private val retry : () -> Unit) :
LoadStateAdapter<MoviesLoadStateAdapter.MoviesLoadStateViewHolder>()
{
override fun onBindViewHolder(holder: MoviesLoadStateViewHolder, loadState: LoadState) {
holder.bind(loadState)
}
override fun onCreateViewHolder(
parent: ViewGroup,
loadState: LoadState
): MoviesLoadStateViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_movie_load_state_footer_view, parent, false)
val binding = ItemMovieLoadStateFooterViewBinding.bind(view)
return MoviesLoadStateViewHolder(binding, retry)
}
inner class MoviesLoadStateViewHolder(private val binding: ItemMovieLoadStateFooterViewBinding,
retry : ()-> Unit) :
RecyclerView.ViewHolder(binding.root) {
init {
binding.retryButton.setOnClickListener {
retry.invoke()
}
}
fun bind(loadState : LoadState){
if(loadState is LoadState.Error){
binding.errorMsg.text = loadState.error.localizedMessage
}
binding.progressBar.visibility = toVisibility(loadState is LoadState.Loading)
}
}
}
这里的目标ProgressBar
应该显示在屏幕中央。
解决方案
我解决了。这是我的代码
在您的活动中
val gridLayoutManager = GridLayoutManager(activity, 2)
gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
val viewType = wallpaperAdapter.getItemViewType(position)
return if(viewType == WALLPAPER_VIEW_TYPE) 1
else 2
}
}
binding.recyclerView.apply {
this.layoutManager = gridLayoutManager
this.setHasFixedSize(true)
this.adapter = wallpaperAdapter
}
在您的 PagingDataAdapter
override fun getItemViewType(position: Int): Int {
if (position == itemCount){
return NETWORK_VIEW_TYPE
}else {
return WALLPAPER_VIEW_TYPE
}
}
希望它对你有用。
推荐阅读
- mongodb - SpringData MongoDb,如何计算不同的查询?
- android - 如何使按钮打开 android studio 中资产上的 PDF 文件中的特定页面?
- javascript - firestore 如何在 JavaScrip 中将 doc.data() 作为对象返回值传递?
- flutter - 关于 Firebase 实时数据库
- python - 如何从两个不同的列表中删除重复项,一个只包含 int,另一个包含混合的 int 和 str?
- bash - 查找没有特定文件 Bash 的文件夹(查找命令)
- javascript - 处理多个唯一的 Express JS 请求
- sql - 如何找到按日期排序的两个连续行,包含特定值?
- javascript - 我无法使用 puppeteer 登录。在下面提供的网站中也找不到登录按钮的选择器
- c# - GetAccountsAsync 总是返回一个空列表