简体   繁体   中英

How to get view binding to work with XML layout heights in RecyclerView.ViewHolder like they did with Kotlin Synthetics?

While trying to convert an application from the defunct Kotlin synthetics to the newer/supported view binding method, I ran into this issue where layouts are inflated but layout_height is being ignored in the inflated layouts. The result is a scrunched up view that doesn't look good.

    inner class InfoAdapter(val data: Array<String>) : androidx.recyclerview.widget.RecyclerView.Adapter<androidx.recyclerview.widget.RecyclerView.ViewHolder>() {
        private val header = 0
        private val item = 1
        private var clickListener: RecyclerClickListener? = null

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): androidx.recyclerview.widget.RecyclerView.ViewHolder {
            when (viewType) {
                item -> return ItemVH(StringRowBinding.inflate(layoutInflater))
                header -> return HeaderVH(InfoHeaderBinding.inflate(layoutInflater))
            }

            return ItemVH(StringRowBinding.inflate(layoutInflater))
        }

...

        inner class ItemVH(private val binding: StringRowBinding): androidx.recyclerview.widget.RecyclerView.ViewHolder(binding.root) {
            init {
                itemView.setOnClickListener { v ->
                    clickListener?.itemClicked(v, adapterPosition)
                }
            }
            fun bind(text: String) {
                binding.title.text = text
            }
        }

...
    }

string_row.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:background="?android:attr/selectableItemBackground">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="16dp"
        android:layout_marginStart="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginEnd="16dp"
        android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>

</RelativeLayout>

The height of the relative layout is supposed to be 48dp but it appears that attribute is being ignored. Data does display and the layout height attribute worked fine with Kotlin synthetics.

I found this SO question related to Activity + view binding but nothing specific for ViewHolder + view binding. Related to the accepted answer of that question is the rhetorical question: What's the point of using the XYZBinding.inflater() method of view binding as recommended by Google to get rid of findViewById() calls if it is just going to ignore margins, height, and width of the inflated layout and the "fix" is basically to NOT use the inflater() call at all and just use findViewById() ? That is, the accepted answer mostly defeats the purpose of inflating views with view binder and reintroduces findViewById() . At any rate, it's not obvious how to adapt that particular answer to this scenario.

The problem is that you're using the overload of inflate() that doesn't specify the parent view. When you do this, any layout_ attributes on the root view are ignored (and replaced by default values). Try this instead:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): androidx.recyclerview.widget.RecyclerView.ViewHolder {
    when (viewType) {
        item -> return ItemVH(StringRowBinding.inflate(layoutInflater, parent, false))
        header -> return HeaderVH(InfoHeaderBinding.inflate(layoutInflater, parent, false))
    }

    return ItemVH(StringRowBinding.inflate(layoutInflater, parent, false))
}

Make sure that you pass false as the third parameter; RecyclerView itself will manage attaching the child views to the parent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM