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!
CodePudding user response:
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()
}