【问题标题】:How to use data binding for Switch onCheckedChageListener event?如何为 Switch onCheckedChageListener 事件使用数据绑定?
【发布时间】:2016-09-13 02:35:25
【问题描述】:

如问题所示,如何将选中的更改侦听器绑定到 xml 中的切换按钮?

我没有使用回收站视图。只是一个简单的布局。

任何帮助表示赞赏。

【问题讨论】:

  • 动态设置有什么问题?
  • 我们可以在项目的其他地方使用相同的视图模型,使用磁盘缓存的可观察字段吗?

标签: android data-binding android-switch


【解决方案1】:

只需使用 ViewModel、liveData 和 Transformations 首先在您的 ViewModel 上

var availabilityState = MutableLiveData<Boolean>(false)
val availabilityText :LiveData<String> =Transformations.map(availabilityState)
{
    if (it == true)
    {
        "Available"
    }else
    {
      "Not Available"
    }
}

然后在你的 XML 上使用

<Switch
android:checked="@={addBookViewModel.availabilityState}"
android:text="@{addBookViewModel.availabilityText}"
...>

就是这样。

【讨论】:

  • 也适用于 androidx.appcompat.widget.SwitchCompat
【解决方案2】:

不同的方式

(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}"
    />

活动中

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)}"
    />

活动中

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匿名类传递给布局

<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}"
    />

活动中

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}"
    />

活动

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]")
    }
}

现在下面将不起作用

现在,如果您在代码中设置 CheckChangeListener 将无法正常工作。因为你不能在一个组件上设置两个回调。绑定已经设置了一个回调,所以你在代码中的回调将不起作用。

罢工>

binding.mySwitch.setOnCheckedChangeListener { buttonView, isChecked ->
    println("buttonView = [$buttonView], isChecked = [$isChecked]")
}

Check CompoundButtonBindingAdapter class 看看 Switch Binding 是如何工作的。

【讨论】:

  • 最后一句话拯救了我的一天。显然我在 RadioGroup 上有 2 个听众,我想知道为什么绑定实现不起作用
  • 有没有办法只使用 xml 来做到这一点? IE。如果我在 xml 中有一个 SwitchPreference 并且我希望它使用自定义布局 android:layout="@layout/custom" 并将该布局传递给数据绑定标题“passedTitle”,我可以使用 成功地做到这一点,如下所示:&lt;include layout="@layout/custom" bind:passedTitle="@{@string/title}" /&gt;,但是如果我只是在偏好中这样做,它不会做任何事情(我得到attribute passedTitle not found):&lt;SwitchPreference android:key="@string/key" layout="@layout/custom" bind:passedTitle="@{@string/title}"
  • 漂亮的答案。用了最后一个
  • 很糟糕,我不能为您提交的每个解决方案加一个。
【解决方案3】:

使用 lambda 表达式和 Switch:

public void onCheckedChanged(boolean checked) {
     // implementation      
}

XML 文件:

<android.support.v7.widget.SwitchCompat
    android:onCheckedChanged="@{(switch, checked) -> item.onCheckedChanged(checked)}"
    ...
/>

其中item 是实现onCheckedChange 方法的类,并像这样导入到XML 文件中:

<data>
    <variable
        name="item"
        type="yourClass"/>
</data>

【讨论】:

  • 我们可以创建一个自定义的 2-way 绑定来减少样板文件
  • @AdityaLadwa 使用checked 属性有什么问题?你可以很容易地绑定它
  • 但是在使用它之后,如果我尝试使用 binding.mySwitch.setChecked(true) 以编程方式检查我的开关,则不会调用 item.onCheckedChanged 方法!!!
  • 找不到接受参数类型“lambda”的 的设置器
【解决方案4】:

您可以通过方法参考来做到这一点:

<CheckBox android:onCheckedChanged="@{callback::checkedChangedListener}".../>

如果您想传递不同的参数,也可以使用 lambda 表达式:

<CheckBox android:onCheckedChanged="@{() -> callback.checked()}".../>

【讨论】:

  • 这对我不起作用我得到Unknown attribute android:onCheckedChanged
  • @TiagoOliveira 虽然我也收到了警告,但在启动应用程序后它似乎确实可以工作
  • @GeorgeMount 为什么我们不能使用 app:onCheckedChangeListener 在 CheckBox 中调用 setOnCheckedChangeListener 方法?
猜你喜欢
  • 1970-01-01
  • 2023-03-19
  • 2022-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-30
  • 2013-03-31
相关资源
最近更新 更多