80

ViewBindings を使用してfindViewById、この典型的なRecyclerView.Adapter初期化コードを置き換えることはできますか? bindingViewHolders はセルごとに異なるため、オブジェクトに val を設定できません。

class CardListAdapter(private val cards: LiveData<List<Card>>) : RecyclerView.Adapter<CardListAdapter.CardViewHolder>() {

    class CardViewHolder(val cardView: View) : RecyclerView.ViewHolder(cardView)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder {
        val binding = CardBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return CardViewHolder(binding.root)
    }

    override fun onBindViewHolder(holder: CardViewHolder, position: Int) {
        val title = holder.cardView.findViewById<TextView>(R.id.title)
        val description = holder.cardView.findViewById<TextView>(R.id.description)
        val value = holder.cardView.findViewById<TextView>(R.id.value)
        // ...
    }
4

9 に答える 9

13

bindingView の代わりに ViewHolder にアタッチします。

class CardViewHolder(val binding: CardBinding) : RecyclerView.ViewHolder(binding.root)

バインディングを渡すと、バインディングはに渡さbinding.rootれますRecyclerView.ViewHolder(binding.root)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder {
    val binding = CardBinding.inflate(LayoutInflater.from(parent.context), parent, false)
    return CardViewHolder(binding)
}

次に、次の方法でどこにでもアクセスします。

holder.binding.title
于 2020-02-27T00:06:31.110 に答える
3

リフレクションに問題がない場合は、これを行うためのはるかに簡単な方法があります。ViewGroup.toBinding() を呼び出すだけで、必要なバインディング オブジェクトを取得できます。ただし、リフレクションについて話しているので、proguard に対しても機能するように proguard-rule を変更する必要があることを覚えておいてください。

// inside adapter
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    return MainViewHolder(parent.toBinding())
}

// ViewHolder
class MainViewHolder(private val binding: AdapterMainBinding) :
    RecyclerView.ViewHolder(binding.root) {

    fun bind(data: String) {
        binding.name.text = data
    }
}

// The magic reflection can reused everywhere.
inline fun <reified V : ViewBinding> ViewGroup.toBinding(): V {
    return V::class.java.getMethod(
        "inflate",
        LayoutInflater::class.java,
        ViewGroup::class.java,
        Boolean::class.java
    ).invoke(null, LayoutInflater.from(context), this, false) as V
}

私はこれらすべてをオープンソースプロジェクトに入れました。あなたも見ることができます. アダプターの使用だけでなく、Activity と Fragment も含まれます。そして何かコメントがあれば教えてください。ありがとう。

https://github.com/Jintin/BindingExtension

于 2020-12-26T00:35:16.653 に答える