74

View Binding 作为 Android Jetpack 的一部分发布

文档:https ://developer.android.com/topic/libraries/view-binding

我的问题是,如何将视图绑定与自定义视图一起使用。Google 文档只有展示的 Activity 和 Fragment。

我试过这个,但什么也没显示。

LayoutInflater inflater = LayoutInflater.from(getContext());

然后,我使用了这个,但又一次,没有运气。

LayoutInflater inflater = (LayoutInflater)
            getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

我想也许我没有针对我的观点选择正确的布局充气器,但不确定。

4

5 回答 5

122

只需通知根,以及是否要附加到它

init { // inflate binding and add as view
    binding = ResultProfileBinding.inflate(LayoutInflater.from(context), this)
}

或者

init { // inflate binding and add as view
    binding = ResultProfileBinding.inflate(LayoutInflater.from(context), this, true)
}

使用哪种膨胀方法取决于 xml 中的根布局类型。

于 2020-04-13T22:11:17.383 回答
20

要使用视图绑定,您需要使用生成的绑定类而不是LayoutInflater,例如,如果布局名称是result_profile.xml那么您需要使用ResultProfileBindingas:

class CustomView @kotlin.jvm.JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    private lateinit var binding: ResultProfileBinding

    init { // inflate binding and add as view
        binding = ResultProfileBinding.inflate(LayoutInflater.from(context))
        addView(binding.root)
    }

}
  1. 自动生成的类:result_profile.xml-> ResultProfileBinding(布局名称,附加Binding
  2. 给绑定充气

    ResultProfileBinding.inflate(LayoutInflater.from(context))
    
  3. 用于addView在层次结构中添加视图:

    addView(binding.root)
    

注意:如果您从ConstraintLayout(是父类)扩展,则使用约束集

于 2020-02-27T12:50:55.143 回答
10

您可以立即初始化视图绑定属性

private val binding = CustomViewBinding.inflate(LayoutInflater.from(context), this)
于 2021-02-17T20:06:07.630 回答
5

如果您尝试将视图绑定与根视图一起使用,这对我有用:

class CustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {

    private lateinit var binding: CustomViewBinding

    override fun onFinishInflate() {
        super.onFinishInflate()
        binding = CustomViewBinding.bind(this)
    }
}
于 2020-02-27T14:09:18.393 回答
1

这是我能想到的最简单的 kotlin 答案。它是一个自定义视图,只包装了一个 TextView 并提供了update(s:String)更新文本的功能。

<!-- view_stub.xml -->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView android:id="@+id/myTextView" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" />
</layout>

// StubView.kt
class StubView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
) : FrameLayout(context,attrs,defStyleAttr) {

    val binding = ViewStubBinding.inflate(context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)
            .also { addView(it.root) }

    fun update(updatedText: String) {
        binding.myTextView.text = updatedText
    }
}

我喜欢这个答案的两点是:

  1. binding是 aval而不是 a var。我尽量限制vars 的数量。
  2. addViewval binding使用also {}范围函数而不是init {}子句密切相关,使得View感觉的实例化更具声明性。

有人可能会争辩说,这addView()确实是一种副作用,应该在该部分中,以便与valinit {}的声明分开。binding我会反对——声明 aval然后将其提供给需要它的代码段对我来说并不像副作用。

于 2020-11-11T00:10:47.687 回答