我只是对这种情况感到好奇,对单向绑定的真正工作方式感到好奇。
我有一个Switch和2个文本视图,它们的颜色与Switch的选中状态绑定在一起
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:textColor="@{swLanguage.checked ? @color/term_condition_gray_1 : @color/term_condition_green_1}"
android:textSize="@dimen/_10ssp" />
<Switch
android:id="@+id/swLanguage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/_8sdp"
android:layout_marginRight="@dimen/_8sdp"
android:thumb="@drawable/term_condition_switch_thumb"
android:track="@drawable/term_condition_switch_track" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:textColor="@{swLanguage.checked ? @color/term_condition_green_1 : @color/term_condition_gray_1}"
android:textSize="@dimen/_10ssp" />
当Java代码中Switch的检查状态更改时,我想做一些额外的动作。但是只要在XML代码中将2个文本视图的颜色与开关的状态绑定在一起,setOnCheckedChangeListener就无法正常工作。
那么这是数据绑定功能本身的问题还是我只是不知道数据绑定是如何工作的?
答案 0 :(得分:0)
您可以将ObservableBoolean与双向绑定连接。
XML
function startAnimation() {
var frames = document.getElementById("animation").children;
var frameCount = frames.length;
var i = 0;
setInterval(function () {
frames[i % frameCount].style.display = "none";
frames[++i % frameCount].style.display = "block";
}, 300);
}
活动
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="activity"
type="someActivity"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:textColor="@{activity.languageChecked ? @color/term_condition_gray_1 : @color/term_condition_green_1}"
android:textSize="@dimen/_10ssp" />
<Switch
android:id="@+id/swLanguage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/_8sdp"
android:layout_marginRight="@dimen/_8sdp"
android:checked="@={activity.languageChecked}"
android:thumb="@drawable/term_condition_switch_thumb"
android:track="@drawable/term_condition_switch_track" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:textColor="@{activity.languageChecked ? @color/term_condition_green_1 : @color/term_condition_gray_1}"
android:textSize="@dimen/_10ssp" />
</LinearLayout>
</layout>
它如何工作?
public ObservableBoolean languageChecked = new ObservableBoolean(false)
变量将更改。languageChecked
变量,则DataBinding的内部过程会将languageChecked
的更改反映到所有绑定对象(在本例中为两个languageChecked
)您可以在Java代码中更改'languageChecked'变量,还可以使用textview
观察该变量的变化
---编辑---
如果您不通过ObservableBoolean和开关本身的addOnPropertyChangedCallback
属性使用双向绑定,则DataBinding将使用InverseBinding来实现此目的。
构建成功后,您可以在Binding Object中观看编写的代码。 (在这种情况下,我的布局名称是test_layout,所以类名称是TestLayoutBindingImpl,因为我使用了DataBindingV2)
checked
在最后一条语句中,他们使用// Inverse Binding Event Handlers
private androidx.databinding.InverseBindingListener swLanguageandroidCheckedAttrChanged = new androidx.databinding.InverseBindingListener() {
@Override
public void onChange() {
synchronized(TestLayoutBindingImpl.this) {
mDirtyFlags |= 0x2 L;
}
requestRebind();
}
};
if ((dirtyFlags & 0x6 L) != 0) {
// read swLanguage.checked
swLanguageChecked = swLanguage.isChecked();
if ((dirtyFlags & 0x6 L) != 0) {
if (swLanguageChecked) {
dirtyFlags |= 0x10 L;
dirtyFlags |= 0x40 L;
} else {
dirtyFlags |= 0x8 L;
dirtyFlags |= 0x20 L;
}
}
// read swLanguage.checked ? @android:color/term_condition_gray_1 : @android:color/term_condition_green_1
swLanguageCheckedMboundView1AndroidColorTermConditionGray1MboundView1AndroidColorTermConditionGreen1 = ((swLanguageChecked) ? (getColorFromResource(mboundView1, R.color.term_condition_gray_1)) : (getColorFromResource(mboundView1, R.color.term_condition_green_1)));
// read swLanguage.checked ? @android:color/term_condition_green_1 : @android:color/term_condition_gray_1
swLanguageCheckedMboundView2AndroidColorTermConditionGreen1MboundView2AndroidColorTermConditionGray1 = ((swLanguageChecked) ? (getColorFromResource(mboundView2, R.color.term_condition_green_1)) : (getColorFromResource(mboundView2, R.color.term_condition_gray_1)));
}
// batch finished
if ((dirtyFlags & 0x6 L) != 0) {
// api target 1
this.mboundView1.setTextColor(swLanguageCheckedMboundView1AndroidColorTermConditionGray1MboundView1AndroidColorTermConditionGreen1);
this.mboundView2.setTextColor(swLanguageCheckedMboundView2AndroidColorTermConditionGreen1MboundView2AndroidColorTermConditionGray1);
}
if ((dirtyFlags & 0x4 L) != 0) {
// api target 1
androidx.databinding.adapters.CompoundButtonBindingAdapter.setListeners(this.swLanguage, (android.widget.CompoundButton.OnCheckedChangeListener) null, swLanguageandroidCheckedAttrChanged);
}
方法向setListeners()
注册OnCheckedChangeListener()。 swLanguageandroidCheckedAttrChanged
使用InverseBindingAdapter观察更改。
由于swLanguageandroidCheckedAttrChanged
使用setListener()
方法来设置侦听器,因此您无法在绑定对象和Java代码之间的代码中操作两个setOnCheckedChangeListener
。
因此,如果要在Java代码(活动)中使用setOnCheckedChangeListener
,请使用ObservableBoolean并通过setOnCheckedChangeListener
观察更改。
如果要比较两个解决方案的结果,请参见Gist