How to deal with recyclerview showing empty row

0

Issue

I am building a movies app that uses "The Movie DB" API.
My app currently displaying a recyclerview filled with movies.

The problem is that some movies don’t have the values I need to display the movie and it looks like this:
https://ibb.co/5FBCP5v

My question is how can I deal with it the correct way ?

  • Should I use recyclerview with 2 view types ?
  • Is there any way I can prevent the row to inflate empty data in the first place ?

This is the recyclerView Adapter:

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)
    }

}

Thank you!

Solution

Filter your items before passing it to recycler view in your activity or your fragment like below

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

Answered By – without_margin

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave A Reply

Your email address will not be published.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More