I'm currently learning Kotlin (specifically consuming APIs) Everything related with the API and his response is fine but I have issues showing the data in a recyclerview and the part of the adapter is little confusing. Debbuging the app step by step I can see the response body go into the adapter but nothing shows of in the recyclerview.
My MainActivity
const val BASE_URL = "https://api.themoviedb.org/"
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(R.layout.activity_main)
getMyData()
}
private fun getMyData() {
val retrofitBuilder = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build()
.create(ApiInterface::class.java)
val retrofitData = retrofitBuilder.getPopularMovies()
retrofitData.enqueue(object : Callback<MoviesResponse?> {
override fun onResponse(
call: Call<MoviesResponse?>,
response: Response<MoviesResponse?>
) {
if(response.isSuccessful){
binding.rvMovie.apply{
setHasFixedSize(true)
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = Adapter(response.body()!!.results)
}
}
}
override fun onFailure(call: Call<MoviesResponse?>, t: Throwable) {
Toast.makeText(this@MainActivity, "${t.message}", Toast.LENGTH_SHORT).show()
}
})
}
}
MainActivity XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.recyclerview.widget.RecyclerView
android:id="@ id/rvMovie"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
>
</androidx.recyclerview.widget.RecyclerView>
</RelativeLayout>
The Adapter
class Adapter(val movieList: List<MyDataItem>):RecyclerView.Adapter<MoviesViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MoviesViewHolder {
val view: LayoutInflater = LayoutInflater.from(parent.context)
return MoviesViewHolder(view.inflate(R.layout.movie_item, parent, false))
}
override fun onBindViewHolder(holder: MoviesViewHolder, position: Int) {
return holder.bindInfo(movieList[position])
}
override fun getItemCount(): Int {
return movieList.size
}
}
class MoviesViewHolder(itemView : View): RecyclerView.ViewHolder(itemView) {
private val binding = MovieItemBinding.bind(itemView)
fun bindInfo(movie: MyDataItem) {
Picasso.get().load("https://image.tmdb.org/t/p/w500${movie.poster_path}").into(binding.moviePhoto)
binding.movieTitle.text = "Title: " movie.title
binding.movieOverview.text = movie.overview
binding.movieRating.text = "Rating : " movie.vote_average.toString()
}
}
individual item's xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
android:id="@ id/movie_photo"
android:contentDescription="Movie Image" />
<TextView
android:layout_below="@ id/movie_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@ id/movie_title"
android:layout_margin="5dp"
android:textSize="15sp"
android:text="Title : "/>
<TextView
android:layout_below="@ id/movie_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@ id/movie_overview"
android:layout_margin="5dp"
android:text="OverView : "/>
<TextView
android:layout_below="@ id/movie_overview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@ id/movie_rating"
android:textSize="15sp"
android:layout_margin="5dp"
android:text="Rating : "/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
CodePudding user response:
If we have a RecyclerView with match_parent as height/width, we should add setHasFixedSize(true) since the size of the RecyclerView itself does not change inserting or deleting items into it.
setHasFixedSize should be false if we have a RecyclerView with wrap_content as height/width since each element inserted by the adapter could change the size of the Recycler depending on the items inserted/deleted, so, the size of the Recycler will be different each time we add/delete items.
To be more clear, if we use
<android.support.v7.widget.RecyclerView
android:id="@ id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
We can use rvMovie.setHasFixedSize(true)
<android.support.v7.widget.RecyclerView
android:id="@ id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Then, we should use rvMovie.setHasFixedSize(false) if we use wrap_content for width or height in our RecyclerView
CodePudding user response:
It may be because you're not actually linking the adapter to your recycler view?
Try adding :
recyclerView.adapter = adapter