【问题标题】:ViewBinding not working for layout included inside RecyclerView itemViewBinding 不适用于 RecyclerView 项目中包含的布局
【发布时间】:2021-04-06 12:58:45
【问题描述】:

这是我的 RecyclerView 项目布局

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

这是 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>

这是访问包含布局中的视图的方式

inner class BarometerVH(private val rvBinding: RvItemHomeSeBarometerBinding) :
            RecyclerView.ViewHolder(rvBinding.root) {
    fun bind(homeItem: HomeItem) {
        rvBinding.layoutSectionHeader.tvProductName.text = homeItem.title
    }
}

我没有编译时错误,但在运行应用程序时出现此异常

java.lang.NullPointerException: Missing required view with ID: com.example.appname:id/layoutSectionHeader

在 Activity 或 Fragment 中包含布局对我有用,但在 Recycler View 中使用时不起作用。

我尝试了此论坛中针对类似异常提供的多种解决方案,但没有一个适用于回收站视图,也没有关于使用

编辑 1:我添加了 RecyclerView 适配器中的重写方法

override fun onCreateViewHolder(
     parent: ViewGroup,
     viewType: Int
) = MarketCommentaryVH(RvItemHomeMarketCommentaryBinding.bind(parent))

override fun onBindViewHolder(
     holder: RecyclerView.ViewHolder,
     position: Int
) {
    holder.bind(homeItemList[position])
}

【问题讨论】:

  • 您好,请提供更多信息。向我们展示您的 RecyclerView 适配器的(相关)部分,以及任何相关内容。
  • @MartinMarconcini,我添加了适配器的覆盖方法,请检查。您可以在第三个代码块中找到 Viewholder。
  • 这很奇怪,但似乎 ViewBinding 在包含的布局方面遇到了问题,可能是因为它没有唯一的 Id(因为它与您一遍又一遍地包含的布局相同)。也许对于那一点,您可能不得不依赖旧的 findViewById。我尚未对此进行测试,因此目前无法为您提供更好的建议。
  • 我认为您需要为包含的布局创建单独的绑定。因此,在 bind() fun 中,您应该执行类似 val layoutSectionHeaderBinding = LayoutSectionHeaderBinding.bind(rvBinding.root) 的操作,而不是参考 tvProductName
  • 感谢@cactustictacs 的回答,我意识到我是直接绑定布局而不膨胀它。

标签: android kotlin android-recyclerview android-viewbinding android-include


【解决方案1】:

RecyclerView 通过创建和重用一组 ViewHolders 来工作,这些ViewHolders 包含视图布局以显示项目的详细信息。您在 onCreateViewHolder 方法中设置这些,您可以:

  • 为项目扩展布局
  • 将该膨胀视图传递给ViewHolder 构造函数

你实际上并没有夸大布局,你正在做

RvItemHomeMarketCommentaryBinding.bind(parent)

而不是

RvItemHomeMarketCommentaryBinding.inflate(LayoutInflater.from(context), parent, false)

(您需要在为ViewHolder 的布局充气时传入parent,这样它才能以正确的尺寸等进行布局)


Binding 组件上的 bind 函数采用已经膨胀的视图层次结构,并尝试查找具有它知道的 ID 的所有组件。例如,它会尝试查找layoutSectionHeader,以便将binding.layoutSectionHeader 分配给该视图。

问题在于,您传入的 parent 布局中不存在该布局,因为这只是 RecyclerView 的布局,它不包含来自 ViewHolder 布局的内容。所以bind 不起作用-视图不在那里绑定。你需要打电话给inflate

【讨论】:

    猜你喜欢
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多