This is my RecyclerView Item Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:orientation="vertical"><!--
android:background="@color/home_item_bg"-->
<include
android:id="@+id/layoutSectionHeader"
layout="@layout/section_header_rv_item_home"/>
<androidx.cardview.widget.CardView
style="@style/Widget.MaterialComponents.CardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp">
<TextView
android:id="@+id/tvMarketAndTerm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="NASDAQ - Medium Term" />
<com.github.mikephil.charting.charts.PieChart
android:id="@+id/pieChart"
android:layout_width="match_parent"
android:layout_height="@dimen/pie_chart_height" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
This is section_header_rv_item_home.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/llSectionHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingTop="12dp"
android:background="?selectableItemBackground"
android:paddingEnd="16dp"
android:paddingBottom="12dp"><!--
android:background="@drawable/ripple_white_light_grey"-->
<TextView
android:id="@+id/tvProductName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textAllCaps="false"
android:textColor="@color/gray"
android:textSize="20sp"
android:textStyle="bold"
tools:text="@string/stock_exchange_barometer" />
<TextView
android:id="@+id/tvSeeAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/see_all"
android:textColor="@color/colorAccent"
android:textSize="13sp"
android:textStyle="bold"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
This is how'm accessing the views inside the included layout
inner class BarometerVH(private val rvBinding: RvItemHomeSeBarometerBinding) :
RecyclerView.ViewHolder(rvBinding.root) {
fun bind(homeItem: HomeItem) {
rvBinding.layoutSectionHeader.tvProductName.text = homeItem.title
}
}
I got no compile time error, but getting this exception when I run the app
java.lang.NullPointerException: Missing required view with ID: com.example.appname:id/layoutSectionHeader
Including a layout in Activity or Fragment works for me, but not working when used in Recycler View.
I tried multiple solutions given in this forum for similar exceptions, but none worked for a recycler view and not question regarding using <include inside recycler view.
Edit 1: I've added the overridden methods from the RecyclerView Adapter
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
) = MarketCommentaryVH(RvItemHomeMarketCommentaryBinding.bind(parent))
override fun onBindViewHolder(
holder: RecyclerView.ViewHolder,
position: Int
) {
holder.bind(homeItemList[position])
}
A RecyclerView
works by creating and reusing a bunch of ViewHolder
s, which hold a view layout to display the details of an item. You set these up in the onCreateViewHolder
method, where you:
ViewHolder
constructorYou're not actually inflating the layout though, you're doing
RvItemHomeMarketCommentaryBinding.bind(parent)
instead of
RvItemHomeMarketCommentaryBinding.inflate(LayoutInflater.from(context), parent, false)
(you need to pass in the parent
while inflating a ViewHolder
's layout, so it can lay itself out with the correct dimensions etc)
The bind
function on a Binding
component takes an already inflated view hierarchy, and tries to find all the components with the IDs it knows about. So for example it tries to find layoutSectionHeader
so it can assign binding.layoutSectionHeader
to that view.
Trouble is, that doesn't exist in the parent
layout you're passing in, because that's just the RecyclerView
's layout, it doesn't contain the stuff from the ViewHolder
layout. So bind
doesn't work - the views aren't there to bind to. You need to call inflate
instead