Reputation: 723
I have implemented a RecyclerView and customer Adapter many times, but for some reason I cannot get this one to display any data. I am feeding in data from JSON using retrofit and calling notifyDataSetChanged() once this has been loaded, yet it still remains blank. I have stripped this back to just one text view to try and simplify but still not getting anything. Can anyone see where I am going wrong here?
When I debug, I am getting the List to contain data so I am definitely parsing the data correctly, I just cant get it display in the recycler view. I have even checked the list.size() in the loadTrailerList method and it has data.
My Activity onCreate method:
trailerAdapter = new TrailerAdapter(this);
trailerRecyclerView = findViewById(R.id.trailer_recycler_view);
trailerRecyclerView.setLayoutManager(new LinearLayoutManager(this));
trailerRecyclerView.setAdapter(trailerAdapter);
Retrofit onResponse method:
if (response.body() != null) {
trailers = response.body().getTrailers();
}
trailerAdapter.loadTrailerList(response.body().getTrailers());
My custom adapter:
public class TrailerAdapter extends RecyclerView.Adapter<TrailerAdapter.TrailerViewHolder> {
private final List<Trailer> trailerList = new ArrayList<>();
private final TrailerClickListener listener;
public TrailerAdapter(TrailerClickListener listener) {
this.listener = listener;
}
@NonNull
@Override
public TrailerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.trailer_list_item, viewGroup, false);
return new TrailerViewHolder(itemView, this);
}
@Override
public void onBindViewHolder(@NonNull TrailerViewHolder trailerViewHolder, int i) {
trailerViewHolder.trailerTitle.setText(trailerList.get(i).getName());
}
@Override
public int getItemCount() {
return trailerList.size();
}
public void loadTrailerList(List<Trailer> trailers) {
this.trailerList.clear();
if (trailers != null) {
trailers.addAll(trailers);
}
notifyDataSetChanged();
}
class TrailerViewHolder extends RecyclerView.ViewHolder {
final TrailerAdapter trailerAdapter;
private final TextView trailerTitle;
private TrailerViewHolder(@NonNull View itemView, TrailerAdapter trailerAdapter) {
super(itemView);
this.trailerAdapter = trailerAdapter;
trailerTitle = itemView.findViewById(R.id.text_view_trailer_title);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onTrailerClicked(trailerList.get(getAdapterPosition()));
}
});
}
}
}
My List Item XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/text_view_trailer_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Play Trailer" />
</LinearLayout>
the recycler view in my activity XML:
<android.support.v7.widget.RecyclerView
android:id="@+id/trailer_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
app:layout_constraintTop_toBottomOf="@+id/trailer_divider">
</android.support.v7.widget.RecyclerView>
I am grateful for anyone that can point me in the right direction
Upvotes: 1
Views: 1185
Reputation: 1
MainActivity.kt-
package com.example.groc
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var foodList : ArrayList<food>
private lateinit var FoodAdapter: foodAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView = findViewById(R.id.recyclerView)
recyclerView.setHasFixedSize(true)
recyclerView.layoutManager=LinearLayoutManager(this)
foodList= ArrayList()
foodList.add(food(R.drawable.pasta,"Pasta"))
foodList.add(food(R.drawable.chicken,"Chicken"))
foodList.add(food(R.drawable.panner,"Paneer"))
foodList.add(food(R.drawable.rajma,"Rajma"))
FoodAdapter= foodAdapter(foodList)
recyclerView.adapter=FoodAdapter
FoodAdapter.onItemClick = {
val intent =Intent(this,DetailedActivity::class.java)
intent.putExtra("food",it)
startActivity(intent)
}
}
}
foodAdapter.kt-
package com.example.groc
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class foodAdapter(private val foodList:ArrayList<food>)
:RecyclerView.Adapter<foodAdapter.FoodViewHolder>(){
var onItemClick : ((food) -> Unit)? =null
class FoodViewHolder(itemView: View):RecyclerView.ViewHolder(itemView){
val imageView : ImageView =itemView.findViewById(R.id.imageView)
val textView : TextView =itemView.findViewById(R.id.textView)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FoodViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.each_item,parent,false)
return FoodViewHolder(view)
}
override fun getItemCount(): Int {
return foodList.size
}
override fun onBindViewHolder(holder: FoodViewHolder, position: Int) {
val food=foodList[position]
holder.imageView.setImageResource(food.image)
holder.textView.text=food.name
holder.itemView.setOnClickListener {
onItemClick?.invoke(food)
}
}
}
food.kt-
package com.example.groc
import android.os.Parcel
import android.os.Parcelable
data class food(val image:Int , val name: String) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readString()!!
) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(image)
parcel.writeString(name)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<food> {
override fun createFromParcel(parcel: Parcel): food {
return food(parcel)
}
override fun newArray(size: Int): Array<food?> {
return arrayOfNulls(size)
}
}
}
DetailedActivity.kt-
package com.example.groc
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
class DetailedActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detailed)
val food = intent.getParcelableExtra<food>("food")
if(food!=null)
{
val textView: TextView=findViewById(R.id.detailedActivityTV)
val imageView: ImageView=findViewById(R.id.detailedActivityIV)
textView.text=food.name
imageView.setImageResource(food.image)
Toast.makeText(this,textView.text,Toast.LENGTH_SHORT).show()
}
}
}
activity_main.xml-
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
each_item.xml-
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="20dp"
android:layout_marginHorizontal="10dp"
android:layout_marginVertical="16dp"
app:cardElevation="4dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imageView"
android:layout_width="120dp"
android:layout_height="100dp"
android:scaleType="fitXY"
android:src="@drawable/pasta"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pasta"
android:textColor="@color/black"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:flow_horizontalBias="0.5"
app:layout_constraintStart_toEndOf="@id/imageView"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
activity_detailed.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DetailedActivity">
<ImageView
android:id="@+id/detailedActivityIV"
android:layout_width="0dp"
android:layout_height="250dp"
android:scaleType="fitXY"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/pasta" />
<TextView
android:id="@+id/detailedActivityTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="TextView"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/detailedActivityIV" />
</androidx.constraintlayout.widget.ConstraintLayout>
Upvotes: 0
Reputation: 1118
It is because you are sending a list to adapter but, you are not initializing your list which is used in the adapter.
try this.
public void loadTrailerList(List<Trailer> trailers) {
this.trailerList.clear();
if (trailers != null) {
trailerList = trailers;
}
notifyDataSetChanged();
}
Upvotes: 1
Reputation: 723
Doh! I just realised what I was doing wrong:
In my loadTrailerList() method in my adapter, I was calling:
trailers.addAll(trailers);
instead of:
trailerList.addAll(trailers);
to load the list of items into the actual ArrayList! whoops!
Upvotes: 0