Androidのデータバインド()基本的な使い方
Androidのデータバインディング(2)イベントハンドラ
Androidのデータバインディング(3)観測可能な
Androidのデータバインド(d)のカスタム属性
のAndroidデータバインディング(5)双方向結合(紙)のカスタムビュー
Androidのデータバインディング(6)のEditTextネクタイTextChangedListenerとFocusChangeListener与えられました
序文
あなたは双方向の結合を達成する必要がある場合は、時間の使用非システム定義のプロパティ場合は、カスタムビューは、@ =行で、カスタムビューにもいくつかの設定を必要としません。
次の例では、結合双方向を実現するカスタムビューを介して説明します。
例は、請求項:
1.ラジオボタンは、(食べる/スリープ/プレイエンドウ豆趣味オプションである)趣味を選択し
、表示画面2をロードするときに初期値が(ラジオボタンへのViewModel広がり式設定値)に関心がある
3。 ViewModelにに渡された値際のRadioButtonは、選択
4.ラジオボタンの値を空にすることができ、あなたが情熱を持っていないことを意味しています、
最初のカスタムのRadioButtonとRADIOGROUP
趣味は、列挙型を定義する必要があり、idでラジオボタンRADIOGROUP時間を選択するように来る、それは第一の結合を達成することができる列挙IDに変換されなければなりません。しかし、我々は彼らが結合列挙型をサポートできるようにするためのRadioButtonとRADIOGROUPをカスタマイズすることができます!
カスタムコードのRadioButtonを初めて目
public class DataBindingRadioButton extends AppCompatRadioButton {
private Integer value;
public DataBindingRadioButton(Context context) {
super(context);
}
public DataBindingRadioButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DataBindingRadioButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
@Override
public void toggle() {
if (isChecked()) {
if (getParent() instanceof RadioGroup) {
// 点击选中的 RadioButton,可以取消选择
((RadioGroup) getParent()).clearCheck();
}
} else {
setChecked(true);
}
}
@BindingAdapter(value = {"value"})
public static void setValue(DataBindingRadioButton radioButton, Integer value) {
radioButton.setValue(value);
ViewParent parent = radioButton.getParent();
if (parent instanceof DataBindingRadioGroup) {
Integer checkedValue = ((DataBindingRadioGroup) parent).getCheckedValue();
radioButton.setChecked(IntegerUtil.isSame(checkedValue, value));
}
}
}
私たちは、値が列挙値の整数に対応する値であり、プロパティ値を定義しDataBindingRadioButtonを与えます。
列挙値は、結合データバインディングを介して来て、対応する方法を設定する必要があります。
私たちは、setValueの(整数値)が、@BindingAdapterで使用していませんでした
さらにDataBindingRadioButtonのパラメータで設定方法を使用して。
理由だけではなく、ラジオボタンを選択された1知るRADIOGROUPの必要性を聞かせて、渡された値です。RADIOGROUPもしOnCheckedChangeはその後、radioButton.setCheckedはRADIOGROUPを通知します、耳を傾けます。
ラジオボタンが選択されていないをサポートするためにあるコードのどの部分トグル()のRadioButton、デフォルトを選択する必要があります。私たちの要求ため、または趣味を持っていないかもしれません。
書かれた2つの整数クラスUtilのを比較するためのコードIntegerUtil。質問は、なぜは整数型の値の値ではなく、intですか?それサポートは愛を選択しないので、Integer型を定義する必要があるので、そう愛する値は、nullにすることができます。
以下は、カスタムコードRADIOGROUPです
@InverseBindingMethods({
@InverseBindingMethod(
type = DataBindingRadioGroup.class,
attribute = "checkedValue",
event = "checkedValueAttrChanged",
method = "getCheckedValue")
})
public class DataBindingRadioGroup extends RadioGroup {
private Integer checkedValue;
private OnValueChangedListener listener;
public DataBindingRadioGroup(Context context) {
super(context);
init();
}
public DataBindingRadioGroup(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public void init() {
setOnCheckedChangeListener((group, checkedId) -> {
if (checkedId > 0) {
DataBindingRadioButton radioButton = (DataBindingRadioButton) findViewById(checkedId);
setCheckedValue(radioButton.isChecked() ? radioButton.getValue() : null);
} else {
setCheckedValue(null);
}
});
}
public Integer getCheckedValue() {
return checkedValue;
}
public void setCheckedValue(Integer checkedValue) {
if (IntegerUtil.isSame(this.checkedValue, checkedValue)) {
return;
}
this.checkedValue = checkedValue;
if (this.checkedValue == null) {
clearCheck();
} else {
DataBindingRadioButton customRadioButton = (DataBindingRadioButton) findViewById(getCheckedRadioButtonId());
if (customRadioButton == null || !IntegerUtil.isSame(this.checkedValue, customRadioButton.getValue())) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof DataBindingRadioButton) {
Integer value = ((DataBindingRadioButton) child).getValue();
if (IntegerUtil.isSame(this.checkedValue, value)) {
((DataBindingRadioButton) child).setChecked(true);
}
}
}
}
}
if (listener != null) {
listener.onValueChanged();
}
}
public void setListener(OnValueChangedListener listener) {
this.listener = listener;
}
public interface OnValueChangedListener {
void onValueChanged();
}
@BindingAdapter("checkedValueAttrChanged")
public static void setValueChangedListener(DataBindingRadioGroup view, final InverseBindingListener bindingListener) {
if (bindingListener == null) {
view.setListener(null);
} else {
// 通知 ViewModel
view.setListener(bindingListener::onChange);
}
}
}
逆結合をサポートするには、最初のクラス名に@InverseBindingMethodsを定義する必要があります。
属性は=「checkedValue」属性は、結合の逆をサポートするために指定されています。
イベント=「checkedValueAttrChanged」指定されているのvalueChangedイベントをリッスン。
方法=「getCheckedValue」逆方向データソースの結合方法は、時間を指定。
イベントとメソッドは、指定されていない場合、デフォルトは自動的に次のルールに生成され、必要とされない
イベント=「xxxAttrChanged」
メソッド=「のgetXXX」
この方法はまた、上記の工程で直接定義することができます。
@InverseBindingAdapter(attribute = "checkedValue", event = "checkedValueAttrChanged")
public Integer getCheckedValue() {
return checkedValue;
}
@BindingAdapter(「checkedValueAttrChanged」)は、それがのonChangeメソッドの、InverseBindingListenerに重点を置いて、リスナーメソッドを指定するために使用され、最終的な通知ビューモデル値の変更を配置することである(この例にInverseBindingListenerを生成されたクラスに実装後、ActivityMainBindingは以下、です)実現InverseBindingListenerを貼り付けます。
private android.databinding.InverseBindingListener mboundView1checkedValueAttrChanged = new android.databinding.InverseBindingListener() {
@Override
public void onChange() {
// Inverse of vm.hobby
// is vm.setHobby((java.lang.Integer) callbackArg_0)
// 这里就是 method = "getCheckedValue" 指定的方法
java.lang.Integer callbackArg_0 = mboundView1.getCheckedValue();
// localize variables for thread safety
// vm != null
boolean vmJavaLangObjectNull = false;
// vm
com.teletian.databindingradiobutton.viewmodel.ViewModel vm = mVm;
// vm.hobby
java.lang.Integer vmHobby = null;
vmJavaLangObjectNull = (vm) != (null);
if (vmJavaLangObjectNull) {
// 这里就是修改 ViewModel 的值
vm.setHobby(((java.lang.Integer) (callbackArg_0)));
}
}
};
物事をsetValueChangedListenerのonChangeメソッドが中に入るためにセットをOnValueChangedListener行うことです。
あなたは、私が直接それが直接OKに割り当てられていないInverseBindingListenerの属性の定義を、なぜわざわざ、頼むかもしれません!
はい、それは確かにそうである、上記のコードは本当に簡単にはそうすることができます!あなたが本当にRADIOGROUP OnValueChangedListenerを設定する必要がある場合でも、それはケースにすることはできません!次のコードは、それほど変更する必要があります
@BindingAdapter(value = {"onCheckedValueChanged", "checkedValueAttrChanged"}, requireAll = false)
public static void setValueChangedListener(DataBindingRadioGroup view,
final OnValueChangedListener valueChangedListener,
final InverseBindingListener bindingListener) {
if (bindingListener == null) {
view.setListener(valueChangedListener);
} else {
view.setListener(() -> {
if (valueChangedListener != null) {
valueChangedListener.onValueChanged();
}
// 通知 ViewModel
bindingListener.onChange();
});
}
}
行うにはsetCheckedValueメソッドの内部では制御が状態を確認し、コンテンツのRadioButtonリスニングを行うことです。
ラジオボタンは、メソッド、setOnCheckedChangeListenerを設定している、その後のinitメソッドをsetChecked、そうsetCheckedValueメソッドが再び呼び出されるコールしているので、サイクル呼び出しを防ぐために、次のコードは必要不可欠です
if (IntegerUtil.isSame(this.checkedValue, checkedValue)) {
return;
}
RADIOGROUPとラジオボタンは、カスタムレイアウトファイルで見てみましょう、終了します
<com.teletian.databindingradiobutton.customview.DataBindingRadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:checkedValue="@={vm.hobby}">
<com.teletian.databindingradiobutton.customview.DataBindingRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="吃饭"
app:value="@{Hobby.EATING.value}" />
<com.teletian.databindingradiobutton.customview.DataBindingRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="睡觉"
app:value="@{Hobby.SLEEPING.value}" />
<com.teletian.databindingradiobutton.customview.DataBindingRadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="打豆豆"
app:value="@{Hobby.ATTACKING_DOUDOU.value}" />
</com.teletian.databindingradiobutton.customview.DataBindingRadioGroup>
アプリによるラジオボタンの最初の値=「@ {Hobby.EATING.value}」を指定するので入れenum値とラジオボタンの値をリンクアップ。
アプリケーションは、その後RADIOGROUPに配置:checkedValue =「@ = {vm.hobby}」双方向バインディングを設定するために。
ソース
https://github.com/teletian/Android/tree/master/DataBindingRadioButton