当使用 <include> 标签包含直接子元素的布局时,Android View 绑定(bind)问题

标签 android android-recyclerview android-viewbinding

我试图包含一个包含唯一 recyclerView 的布局。

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" />

并将其包含在主布局中,如下所示。

<?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>

在这种情况下,它会给我一个错误,例如,

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

生成的 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));
  }
}

如果我使用任何父布局(如框架布局)包装 recyclerView ,它会很好地工作,但我不想将我的 recyclerView 包装在任何其他 View 中。

请为我提供一个解决方案,在这种情况下(RecyclerView),我怎样才能将布局包含在直接 subview 中,而在Viewbounding中没有任何根或父 View 组?

最佳答案

当您将 ID 提供给 <include> 时意味着您正在将 id 设置为您所包含的布局的 Root View 。在这种情况下,您将 id 设置为回收器 View ,这就是为什么它无法找到具有原始 ID 的回收器 View 。你需要做的是

  1. 使用<merge>在共享布局内。
  2. 包裹你的RecyclerView<merge> .
  3. 不要给<include>任何 ID。
  4. 调用bind()生成的合并布局类的方法,并传递您包含布局的布局的 Root View 。
  5. 从合并绑定(bind)的对象访问您的 View

例如,您有 home_recycler_view.xml所以你会有HomeRecyclerView.class生成的,这就是您从此布局访问 View 的方式。

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()
    }
}

关于当使用 <include> 标签包含直接子元素的布局时,Android View 绑定(bind)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61127847/

相关文章:

Android 6 - fullBackupContent 问题

java - ListView 适配器异步操作

android - 自定义注释,如用于 android viewBinding 的 Butterknifes "@OnClick"

android - Kotlin :How To Call a View within a Function Using ViewBinding

android - 将日期绑定(bind)到 SQLiteStatement

android - android布局中的错误定位

java - Gradle 返回包不存在

android - 单击不处理 fragment 内的 RecyclerView 项目

java - SnapHelper 项目位置

android - 在 View 被销毁后从另一个线程访问 AutoClearedValue