Android viewbinding problem when including layout with the <include> tag with direct child in it

Viewed 3647

I am trying to include a layout that contains the only recyclerView in it.

home_recycler_view.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/home_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingStart="@dimen/_8sdp"
android:paddingEnd="@dimen/_8sdp" />

And include this in the main layout like below.

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include
        android:id="@+id/slider_recyclerView"
        layout="@layout/home_recycler_view" />

    <include
        android:id="@+id/boards_recyclerview"
        layout="@layout/home_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/_12sdp" />

    <include
        android:id="@+id/news_recyclerview"
        layout="@layout/home_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/_12sdp" />

    <include
        android:id="@+id/video_recyclerview"
        layout="@layout/home_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/_12sdp"
        android:layout_marginBottom="@dimen/_2sdp" />

</LinearLayout>

In this case, it gives me an error like,

java.lang.NullPointerException: Missing required view with ID: homeRecyclerView

Generated Class Of home_recycler_view.xml

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;
import com.backendme.arduinolearn.R;
import java.lang.NullPointerException;
import java.lang.Override;
import java.lang.String;

public final class HomeRecyclerViewBinding implements ViewBinding {
  @NonNull
  private final RecyclerView rootView;

  @NonNull
  public final RecyclerView homeRecyclerView;

  private HomeRecyclerViewBinding(@NonNull RecyclerView rootView,
      @NonNull RecyclerView homeRecyclerView) {
    this.rootView = rootView;
    this.homeRecyclerView = homeRecyclerView;
  }

  @Override
  @NonNull
  public RecyclerView getRoot() {
    return rootView;
  }

  @NonNull
  public static HomeRecyclerViewBinding inflate(@NonNull LayoutInflater inflater) {
    return inflate(inflater, null, false);
  }

  @NonNull
  public static HomeRecyclerViewBinding inflate(@NonNull LayoutInflater inflater,
      @Nullable ViewGroup parent, boolean attachToParent) {
    View root = inflater.inflate(R.layout.home_recycler_view, parent, false);
    if (attachToParent) {
      parent.addView(root);
    }
    return bind(root);
  }

  @NonNull
  public static HomeRecyclerViewBinding bind(@NonNull View rootView) {
    // The body of this method is generated in a way you would not otherwise write.
    // This is done to optimize the compiled bytecode for size and performance.
    String missingId;
    missingId: {
      RecyclerView homeRecyclerView = rootView.findViewById(R.id.home_recycler_view);
      if (homeRecyclerView == null) {
        missingId = "homeRecyclerView";
        break missingId;
      }
      return new HomeRecyclerViewBinding((RecyclerView) rootView, homeRecyclerView);
    }
    throw new NullPointerException("Missing required view with ID: ".concat(missingId));
  }
}

if I wrap the recyclerView with any parent layout like frame layout than it works fine but I don't want to wrap my recyclerView in any other view.

please provide me a solution for this how can I include layout with a direct child in this case (RecyclerView) without any root or parent viewGroup in Viewbinding?

1 Answers

When you give ID to <include> means you are setting the id to root view of the layout you're including. In this case, you're setting the id to your recycler view and that's why It can not find the recycler view with its original ID. What you need to do is

  1. use <merge> within the shared layout.
  2. Wrap your RecyclerView in <merge>.
  3. Don't give <include> any ID.
  4. Call the bind() method of the generated class of merge layout and pass the root view of the layout you included your layout in.
  5. Access your view from the object of merge binding

For example, you have home_recycler_view.xml so you'll have HomeRecyclerView.class generated and this is how you will access the view from this layout.

class TestActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = ActivityTestBinding.inflate(layoutInflater)
        val homeRecyclerBinding= HomeRecyclerView.bind(binding.root)
        setContentView(binding.root)
        homeRecyclerBinding.homeRecyclerView.adapter= SomeAdapter()
    }
}
Related