android 数据绑定开关侦听器不工作
android databinding switch listener doesn't work
所以我创建了 val isSwitchChecked = ObservableBoolean(false)
变量并像这样 android:checked="@={viewmodel.isSwitchChecked()}"
添加到开关上的 XML 因为我想在加载数据时使用布尔值检查它并且一切正常直到我添加 OnCheckedChangeListener
然后 switch 不会对侦听器做出反应,除非我从 xml 中删除这个 android:checked="@={viewmodel.isSwitchChecked()}"
。这是怎么回事?我怎样才能让它双向工作?
你的做法是错误的。
失败原因
如果您在 Switch 上设置双向绑定,那么 OnCheckedChangeListener
以编程方式将不起作用。因为内部双向绑定依赖于 OnCheckedChangeListener
.
正确的方法
如果您正在进行双向绑定,那么也可以通过绑定来设置检查更改侦听器。我告诉你一些方法。
以下是在数据绑定中设置OnCheckedChangeListener
的方法:
(1) 由 method expression
设置
布局中
<variable
name="activity"
type="com.innovanathinklabs.sample.activities.CalendarActivity"/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={model.checked}"
android:onCheckedChanged="@{activity::onGenderChanged}"
/>
在Activity
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
binding.activity = this
binding.model = Model()
}
fun onGenderChanged(buttonView: CompoundButton, isChecked: Boolean) {
println("buttonView = [$buttonView], isChecked = [$isChecked]")
}
}
(2) 通过lambda expression 设置和方法调用
<variable
name="model"
type="com.innovanathinklabs.sample.data.Model"/>
<variable
name="activity"
type="com.innovanathinklabs.sample.activities.HomeActivity"/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={model.checked}"
android:onCheckedChanged="@{(button, bool)-> activity.saveGender(bool)}"
/>
在Activity
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
binding.activity = this
binding.model = Model()
}
fun saveGender(isChecked: Boolean) {
println("isChecked = [$isChecked]")
}
}
(3) 将 OnCheckedChangeListener
匿名 class 传递给布局
<variable
name="onGenderChange"
type="android.widget.CompoundButton.OnCheckedChangeListener"/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={model.checked}"
android:onCheckedChanged="@{onGenderChange}"
/>
在Activity
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
binding.model = Model()
binding.setOnGenderChange { buttonView, isChecked ->
println("buttonView = [$buttonView], isChecked = [$isChecked]")
}
}
}
(4) 通过引用OnCheckedChangeListener
<variable
name="onGenderChange2"
type="android.widget.CompoundButton.OnCheckedChangeListener"/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={model.checked}"
android:onCheckedChanged="@{onGenderChange2}"
/>
Activity
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
binding.model = Model()
binding.onGenderChange2 = onGenderChange
}
private val onGenderChange: CompoundButton.OnCheckedChangeListener = CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
println("buttonView = [$buttonView], isChecked = [$isChecked]")
}
}
这永远行不通
因为你不能在一个组件上设置两个回调。已经通过双向绑定设置了一个回调,因此您的回调将不起作用。
binding.mySwitch.setOnCheckedChangeListener { buttonView, isChecked ->
println("buttonView = [$buttonView], isChecked = [$isChecked]")
}
Check CompoundButtonBindingAdapter class 查看 Switch Binding 的工作原理。
所以我创建了 val isSwitchChecked = ObservableBoolean(false)
变量并像这样 android:checked="@={viewmodel.isSwitchChecked()}"
添加到开关上的 XML 因为我想在加载数据时使用布尔值检查它并且一切正常直到我添加 OnCheckedChangeListener
然后 switch 不会对侦听器做出反应,除非我从 xml 中删除这个 android:checked="@={viewmodel.isSwitchChecked()}"
。这是怎么回事?我怎样才能让它双向工作?
你的做法是错误的。
失败原因
如果您在 Switch 上设置双向绑定,那么 OnCheckedChangeListener
以编程方式将不起作用。因为内部双向绑定依赖于 OnCheckedChangeListener
.
正确的方法
如果您正在进行双向绑定,那么也可以通过绑定来设置检查更改侦听器。我告诉你一些方法。
以下是在数据绑定中设置OnCheckedChangeListener
的方法:
(1) 由 method expression
设置布局中
<variable
name="activity"
type="com.innovanathinklabs.sample.activities.CalendarActivity"/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={model.checked}"
android:onCheckedChanged="@{activity::onGenderChanged}"
/>
在Activity
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
binding.activity = this
binding.model = Model()
}
fun onGenderChanged(buttonView: CompoundButton, isChecked: Boolean) {
println("buttonView = [$buttonView], isChecked = [$isChecked]")
}
}
(2) 通过lambda expression 设置和方法调用
<variable
name="model"
type="com.innovanathinklabs.sample.data.Model"/>
<variable
name="activity"
type="com.innovanathinklabs.sample.activities.HomeActivity"/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={model.checked}"
android:onCheckedChanged="@{(button, bool)-> activity.saveGender(bool)}"
/>
在Activity
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
binding.activity = this
binding.model = Model()
}
fun saveGender(isChecked: Boolean) {
println("isChecked = [$isChecked]")
}
}
(3) 将 OnCheckedChangeListener
匿名 class 传递给布局
<variable
name="onGenderChange"
type="android.widget.CompoundButton.OnCheckedChangeListener"/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={model.checked}"
android:onCheckedChanged="@{onGenderChange}"
/>
在Activity
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
binding.model = Model()
binding.setOnGenderChange { buttonView, isChecked ->
println("buttonView = [$buttonView], isChecked = [$isChecked]")
}
}
}
(4) 通过引用OnCheckedChangeListener
<variable
name="onGenderChange2"
type="android.widget.CompoundButton.OnCheckedChangeListener"/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={model.checked}"
android:onCheckedChanged="@{onGenderChange2}"
/>
Activity
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = DataBindingUtil.setContentView<ActivityCalendarBinding>(this, R.layout.activity_calendar)
binding.model = Model()
binding.onGenderChange2 = onGenderChange
}
private val onGenderChange: CompoundButton.OnCheckedChangeListener = CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
println("buttonView = [$buttonView], isChecked = [$isChecked]")
}
}
这永远行不通
因为你不能在一个组件上设置两个回调。已经通过双向绑定设置了一个回调,因此您的回调将不起作用。
binding.mySwitch.setOnCheckedChangeListener { buttonView, isChecked ->
println("buttonView = [$buttonView], isChecked = [$isChecked]")
}
Check CompoundButtonBindingAdapter class 查看 Switch Binding 的工作原理。