So, I've been debugging for a while, and I can't seem to find where my error is. On my Debug console it shows the size of item list I am receiving from the response, with the data associated with each item in the list. It also shows the id of the textviews I set on the Adapter, but when I load the app I only get the Toast message I set on my fragment to verify I am receiving data, but no data on my textviews
ListFragment
class ListFragment : Fragment() {
private val spaceVM : MainViewModel by viewModels()
private lateinit var spaceAdapter: SpaceAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_list, container, false)
}
override fun onResume() {
super.onResume()
setUpObserver()
}
private fun setUpObserver(){
spaceVM.spaceLiveData.observe(this, Observer {
val data = spaceVM.spaceLiveData.value
if (data != null) {
Toast.makeText(context, data.toString(), Toast.LENGTH_LONG).show()
//ID of my recycler view using Kotlin Android Extensions
rvSpace.apply {
layoutManager = LinearLayoutManager(activity)
spaceAdapter = SpaceAdapter()
spaceAdapter.submitSpaceList(data)
adapter = spaceAdapter
}
}
})
}
}
SpaceAdapter
class SpaceAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var items : List<SpaceXResponse> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return SpaceViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.card, parent, false)
)
}
override fun getItemCount(): Int {
return items.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when(holder){
is SpaceViewHolder ->{
holder.bind(items.get(position))
}
}
}
fun submitSpaceList(spaceList : List<SpaceXResponse>){
items = spaceList
}
class SpaceViewHolder constructor(itemView: View) : RecyclerView.ViewHolder(itemView){
val missionName : TextView = itemView.tvMissionName
val rocketName : TextView = itemView.tvRocketName
val launchSite : TextView = itemView.tvLaunchSite
val dol : TextView = itemView.tvDOL
fun bind(spacePost : SpaceXResponse){
missionName.setText(spacePost.missionName)
rocketName.setText(spacePost.rocket?.rocketName)
launchSite.setText(spacePost.launchSite?.siteName)
dol.setText(spacePost.launchDateLocal)
}
}
}
Maybe it could be the way I set my holder on onBindViewHolder? I put a debug breakpoint on it and i get: "ViewHolder{e0b3537 position =0 id=-1, oldPos=-1, pLpos:-1 no parent}" But I feel like I added the parent already on onCreateViewHolder
Here is my Fragment xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".view.ListFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toTopOf="@+id/card"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvSpace"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
And here is my Card xml I am trying to inflate into my RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="10dp"
android:gravity="center"
app:layout_constraintBottom_toTopOf="@+id/card"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="305dp">
<TextView
android:id="@+id/tvMissionName"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/tvRocketName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvRocketName"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/tvLaunchSite"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvMissionName" />
<TextView
android:id="@+id/tvLaunchSite"
android:layout_width="match_parent"
android:layout_height="0dp"
android:text="@{space.launchSite.siteName}"
app:layout_constraintBottom_toTopOf="@id/tvDOL"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvRocketName" />
<TextView
android:id="@+id/tvDOL"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/ivImage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvLaunchSite" />
<ImageView
android:id="@+id/ivImage"
android:layout_width="350px"
android:layout_height="350px"
android:src="@drawable/ic_launcher_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
I think, you lost notifyDatasetChanged
call on your adapter.
Also xml of viewholder looks bit suspicious, it's height is 0 and it uses height constrain on nonexistent id app:layout_constraintBottom_toTopOf="@+id/card"
. After all, you can narrow error place, you can set log in on bindviewholder, to get if data is set. If adapter binds holder proper number of times - then problem is in viewholder code