我的活动类中有一个ObservableBoolean
字段,该字段绑定到"已检查"我ToggleButton
的属性如此:
android:checked="@{activity.editing}"
我希望这会在按钮和布尔值之间创建一个双向关系,但它只会从字段到按钮进行更改,而不是其他方式。我做错了什么,或者这不在Android DataBinding
的范围内?
答案 0 :(得分:36)
你需要另一个' ='告诉Android你想要使用双向数据绑定:
CurrentValue
您可以在in the wordpress article of George Mount找到更多相关信息:
双向数据绑定
Android不会受到典型数据输入的影响,将用户输入的变化反映回模型通常很重要。例如,如果上述数据是以联系形式出现的,那么将编辑后的文本推回到模型中而不必从EditText中提取数据会很不错。这是你如何做到的:
NewValue
非常漂亮,嗯?这里唯一的区别是表达式标有
e.NewValue = CheckState.Unchecked
而不是android:checked="@={activity.editing}"
。预计大多数数据绑定将继续是单向的,我们不希望创建所有这些监听器并观察永远不会发生的变化。
答案 1 :(得分:5)
无需使用ObservableBoolean
,您可以通过布尔变量的常规getter-setter方法执行此操作。在你的模型类中就像这样
public class User{
private boolean checked;
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
}
在ToggleButton
上执行双向绑定。
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={user.checked}"/>
并使用绑定变量获取此值。
binding.getUser().isChecked()
答案 2 :(得分:2)
这是一个使用Switch的双向数据绑定的简单示例,它也具有Checked属性,如ToggleButton。
Item.java:
import android.databinding.BaseObservable;
import android.databinding.Bindable;
public class Item extends BaseObservable {
private Boolean checked;
@Bindable
public Boolean getChecked() {
return this.checked;
}
public void setChecked(Boolean checked) {
this.checked = checked;
notifyPropertyChanged(BR.checked);
}
}
MainActivity.java:
public class MainActivity extends AppCompatActivity {
public Item item;
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
item = new Item();
item.setChecked(true);
/* By default, a Binding class will be generated based on the name of the layout file,
converting it to Pascal case and suffixing “Binding” to it.
The above layout file was activity_main.xml so the generate class was ActivityMainBinding */
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setItem(item);
}
public void button_onClick(View v) {
item.setChecked(!item.getChecked());
}
}
activity_main.xml中:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="item"
type="com.example.abc.twowaydatabinding.Item" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Switch
android:id="@+id/switch_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={item.checked}" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="change"
android:onClick="button_onClick"/>
</LinearLayout>
</layout>
的build.gradle:
android {
...
dataBinding{
enabled=true
}
}
来源文档:https://developer.android.com/topic/libraries/data-binding/index.html
答案 3 :(得分:1)
以下是在数据绑定中设置OnCheckedChangeListener
的方法:
在布局中
<variable
name="activity"
type="com.innovanathinklabs.sample.activities.CalendarActivity"/>
<ToggleButton
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]")
}
}
<variable
name="model"
type="com.innovanathinklabs.sample.data.Model"/>
<variable
name="activity"
type="com.innovanathinklabs.sample.activities.HomeActivity"/>
<ToggleButton
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]")
}
}
OnCheckedChangeListener
匿名类传递给布局<variable
name="onGenderChange"
type="android.widget.CompoundButton.OnCheckedChangeListener"/>
<ToggleButton
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]")
}
}
}
OnCheckedChangeListener
<variable
name="onGenderChange2"
type="android.widget.CompoundButton.OnCheckedChangeListener"/>
<ToggleButton
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]")
}
}
因为您不能在一个组件上设置两个回调。已经通过两种方式绑定设置了一个回调,因此您的回调将不起作用。
binding.toggleButton.setOnCheckedChangeListener { buttonView, isChecked ->
println("buttonView = [$buttonView], isChecked = [$isChecked]")
}
Check CompoundButtonBindingAdapter class,了解Switch Binding的工作原理。