如何从 BindingAdapter 访问数据绑定变量
How to access data binding variable from a BindingAdapter
例如,我的数据绑定中有以下变量 XML。
<layout ...>
<data>
<variable name="listener" type="com.xyz.Listener" />
<!-- and other variables -->
</data>
...
</layout>
我在我的每一个数据绑定布局中都使用了这个变量,并且我需要在我的几乎每一个 @BindingAdapter
中访问它。例如,我的绑定适配器大多是这样的。
@BindingAdapter("board")
fun setBoard(view: TextView, board: Board) {
view.setText(board.name)
view.setOnClickListener {
listener.onBoardClicked(board)
}
}
@BindingAdapter("topic")
fun setTopic(view: TextView, topic: Topic) {
view.setText(topic.name)
view.setOnClickListener {
listener.onTopicClicked(topic)
}
}
// and a few others like that
我是这样使用它们的
<TextView ... app:board="@{board}" ... />
<TextView ... app:topic="@{topic}" ... />
我在这里需要的是一种方法来访问 data
块中声明的 listener
变量到我的所有绑定适配器。有没有办法做到这一点,而无需每次都手动将其作为第二个变量传递?
// I know I can do this - looking for an alternative
@BindingAdapter({"board", "listener"})
fun setBoard(view: TextView, board: Board, listener: Listener) {
view.setText(board.name)
view.setOnClickListener {
listener.onBoardClicked(board)
}
}
我在这里使用的是 Kotlin,但 Java 中的解决方案对我来说也很好用。
经过更多研究,我发现了 DataBindingComponent
界面,它正好解决了我遇到的问题。显然,如果您将绑定适配器设为实例方法而不是静态方法,编译器将采用您在其中声明它的 class,并将其添加为 DataBindingComponent
的 属性。所以我制作了我的绑定适配器实例方法,并通过构造函数注入了我想要的变量。
class Binding(val listener: Listener) {
@BindingAdapter("board")
fun setBoard(view: TextView, board: Board) {
view.setText(board.name)
view.setOnClickListener {
listener.onBoardClicked(board)
}
}
@BindingAdapter("topic")
fun setTopic(view: TextView, topic: Topic) {
view.setText(topic.name)
view.setOnClickListener {
listener.onTopicClicked(topic)
}
}
}
构建后,编译生成如下界面
package android.databinding;
public interface DataBindingComponent {
com.my.package.Binding getBinding();
}
然后我通过使绑定 class 扩展此接口和 return 本身
来完成循环
class Binding(val listener: Listener) : DataBindingComponent {
override fun getBinding(): Binding {
return this
}
// all the other stuff
}
这允许我在膨胀视图时将其作为参数传递,因此我什至不再需要将 listener
声明为 XML 变量。我可以只声明 Binding
实例
val bindingComponent = Binding(object : Listener {
// implement listener methods here
})
并在给布局充气时传递
// now I can use it in activities
DataBindingUtil.setContentView<MyActivityBinding>(
this, R.layout.my_activity, bindingComponent)
// ...or in fragments
DataBindingUtil.inflate<MyFragmentBinding>(
inflater, R.layout.my_fragment, parent, false)
// ...or any other place DataBindingUtil allows
例如,我的数据绑定中有以下变量 XML。
<layout ...>
<data>
<variable name="listener" type="com.xyz.Listener" />
<!-- and other variables -->
</data>
...
</layout>
我在我的每一个数据绑定布局中都使用了这个变量,并且我需要在我的几乎每一个 @BindingAdapter
中访问它。例如,我的绑定适配器大多是这样的。
@BindingAdapter("board")
fun setBoard(view: TextView, board: Board) {
view.setText(board.name)
view.setOnClickListener {
listener.onBoardClicked(board)
}
}
@BindingAdapter("topic")
fun setTopic(view: TextView, topic: Topic) {
view.setText(topic.name)
view.setOnClickListener {
listener.onTopicClicked(topic)
}
}
// and a few others like that
我是这样使用它们的
<TextView ... app:board="@{board}" ... />
<TextView ... app:topic="@{topic}" ... />
我在这里需要的是一种方法来访问 data
块中声明的 listener
变量到我的所有绑定适配器。有没有办法做到这一点,而无需每次都手动将其作为第二个变量传递?
// I know I can do this - looking for an alternative
@BindingAdapter({"board", "listener"})
fun setBoard(view: TextView, board: Board, listener: Listener) {
view.setText(board.name)
view.setOnClickListener {
listener.onBoardClicked(board)
}
}
我在这里使用的是 Kotlin,但 Java 中的解决方案对我来说也很好用。
经过更多研究,我发现了 DataBindingComponent
界面,它正好解决了我遇到的问题。显然,如果您将绑定适配器设为实例方法而不是静态方法,编译器将采用您在其中声明它的 class,并将其添加为 DataBindingComponent
的 属性。所以我制作了我的绑定适配器实例方法,并通过构造函数注入了我想要的变量。
class Binding(val listener: Listener) {
@BindingAdapter("board")
fun setBoard(view: TextView, board: Board) {
view.setText(board.name)
view.setOnClickListener {
listener.onBoardClicked(board)
}
}
@BindingAdapter("topic")
fun setTopic(view: TextView, topic: Topic) {
view.setText(topic.name)
view.setOnClickListener {
listener.onTopicClicked(topic)
}
}
}
构建后,编译生成如下界面
package android.databinding;
public interface DataBindingComponent {
com.my.package.Binding getBinding();
}
然后我通过使绑定 class 扩展此接口和 return 本身
来完成循环class Binding(val listener: Listener) : DataBindingComponent {
override fun getBinding(): Binding {
return this
}
// all the other stuff
}
这允许我在膨胀视图时将其作为参数传递,因此我什至不再需要将 listener
声明为 XML 变量。我可以只声明 Binding
实例
val bindingComponent = Binding(object : Listener {
// implement listener methods here
})
并在给布局充气时传递
// now I can use it in activities
DataBindingUtil.setContentView<MyActivityBinding>(
this, R.layout.my_activity, bindingComponent)
// ...or in fragments
DataBindingUtil.inflate<MyFragmentBinding>(
inflater, R.layout.my_fragment, parent, false)
// ...or any other place DataBindingUtil allows