【问题标题】:How to deal with recyclerview showing empty row如何处理显示空行的recyclerview
【发布时间】:2021-12-26 08:29:20
【问题描述】:

我正在构建一个使用“电影数据库”API 的电影应用程序。 我的应用目前正在显示一个充满电影的回收站视图。

问题是某些电影没有显示电影所需的值,它看起来像这样: https://ibb.co/5FBCP5v

我的问题是如何正确处理它?

  • 我应该使用具有 2 种视图类型的 recyclerview 吗?
  • 有什么方法可以防止该行首先膨胀空数据?

这是 recyclerView 适配器:

class MainRecyclerViewAdapter(var moviesList: List<Movie>,var listener : MainRecyclerViewAdapter.MovieListener) :
    RecyclerView.Adapter<MainRecyclerViewAdapter.MovieHolder>() {

    inner class MovieHolder(var itemView : View) : RecyclerView.ViewHolder(itemView),
        View.OnClickListener {

        fun bindViews(movie : Movie){

            val imageBaseUrl = "https://image.tmdb.org/t/p/w185"

            val movieTitle = itemView.findViewById<TextView>(R.id.movieTitle)
            val movieYear = itemView.findViewById<TextView>(R.id.movieYear)
            val movieImage = itemView.findViewById<ImageView>(R.id.movieImage)

            //Rating Bar
            val ratingBar = itemView.findViewById<RatingBar>(R.id.ratingBar)
            val ratingInNumbers = itemView.findViewById<TextView>(R.id.ratingInNumbers)
            val peopleRated = itemView.findViewById<TextView>(R.id.peopleRated)
            

            itemView.setOnClickListener(this)
            

            if (movie.movieName != "null" && movie.movieVoteCount != "null" && movie.movieVoteCount != "null") {

               
                // Movie Name
                movieTitle.text = movie.movieName

                // Movie Year
                val inputFormat = SimpleDateFormat("yyyy", Locale.getDefault())
                if (movie.movieReleasedDate != null && movie.movieReleasedDate.isNotEmpty()){
                    val date = inputFormat.parse(movie.movieReleasedDate)
                    val movieYearString: String = inputFormat.format(date?.time)
                    movieYear.text = movieYearString
                }


                // Image
                Glide.with(itemView.context).load(imageBaseUrl + movie.moviePoster).into(movieImage)
                Log.e("ImageuRL", "URL: " + movie.moviePoster)

                // Rating Bar
                if (movie.movieVotesAverge != null){
                    val ratingDivider = movie.movieVotesAverge.toDouble() / 2
                    ratingBar.rating = ratingDivider.toFloat()
                    ratingInNumbers.text = ratingDivider.toString()
                }

                
                // Rating
                if (movie.movieVoteCount != null){
                    movie.movieVoteCount = when {
                        abs(movie.movieVoteCount.toDouble() / 1000000) > 1 -> {
                            (movie.movieVoteCount.toDouble() / 1000000).toString().toString() + "m"
                        }
                        abs(movie.movieVoteCount.toDouble() / 1000) > 1 -> {
                            (movie.movieVoteCount.toDouble() / 1000).toString().toString() + "k"
                        }
                        else -> {
                            movie.movieVoteCount.toInt().toString()
                        }
                    }
                }


                val ratedPeopleString = "(${movie.movieVoteCount})"
                peopleRated.text = ratedPeopleString

            }


        }

        override fun onClick(view: View?) {
            val position = adapterPosition
            listener.onMovieClickedListener(moviesList[position])
        }


    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieHolder {
        val rootView = LayoutInflater.from(parent.context).inflate(R.layout.recycler_view_row_change,parent,false)
        return MovieHolder(rootView)
    }

    override fun onBindViewHolder(holder: MovieHolder, position: Int) {
        holder.bindViews(moviesList[position])
    }

    override fun getItemCount(): Int {
        return moviesList.size
    }

    fun changeCurrentList(newMovieList : List<Movie>) {
        this.moviesList = newMovieList
        notifyDataSetChanged()
    }

    interface MovieListener{
        fun onMovieClickedListener(movie:Movie)
    }

}

谢谢!

【问题讨论】:

  • 在将数据传递给适配器之前准备好数据。过滤无效的整体并仅将您想要显示的内容传递给适配器。有意义吗?
  • 不多,我正在向适配器传递电影列表。在将它们传递给适配器之前如何过滤它们?
  • 在创建 MainRecyclerViewAdapter 对象之前,检查电影列表并删除无效条目。

标签: android kotlin android-recyclerview android-adapter android-mvvm


【解决方案1】:

过滤您的项目,然后将其传递到您的活动或片段中的回收站视图,如下所示

moviesList.filter{ movie ->
    movie != null && 
    !movie.movieName.isNullOrEmpty() &&
    !movie.movieVoteCount.isNullOrEmpty() &&
    !movie.movieVoteCount.isNullOrEmpty() &&
    !movie.moviePoster.isNullOrEmpty()
}

【讨论】:

  • 感谢您的回答,我试过了,但它不起作用。但是当我在 null 检查它的作品后创建一个新列表时。你知道为什么吗 ?因为使用过滤器属性比创建新列表更有效...
  • 您必须再次将过滤后的列表传递给您的列表,movieList = movieList.filter {...},然后将其传递给您的适配器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-21
  • 2015-03-28
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多