gpt4 book ai didi

android - 是否可以将一个 ObservableField 绑定(bind)到另一个?

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:56:30 33 4
gpt4 key购买 nike

我明白 Android's data-binding library 的目的用于观察数据并在数据更改时自动更新的 View 。

问题:数据是否可以观察到其他数据?例如,我能否让一个 ObservableField“依赖于”或“绑定(bind)到”另一个或一组其他 ObservableField 的值?目前,我已经手动实现了这一点 - 每次“依赖者”ObservableField 发生变化时,我都会计算依赖字段并更新其值。

详情

我的用例是我希望所有“逻辑”都在 View 之外 - 所以我想将我所有的逻辑放在“数据”类中(ViewModel,如果可以的话)。我有一个按钮,我想根据其他几个字段的内容将其状态设置为启用/禁用。这个例子说明了我的想法。

我的布局文件是这样的

<layout>
<data>
<variable name="register" class="com.example.RegisterViewModel"/>
</data>
<LinearLayout>
<EditText
android:id="@+id/edUsername"
android:text="@{register.username}"/>
<EditText android:id="@+id/edPassword" />
<EditText android:id="@+id/edConfirm" />
<Button android:text="Register" android:enabled="@{register.isValid}" />
</LinearLayout>
</layout>

而且,我的View代码如下:

class RegisterView extends View {
@Override
protected void onFinishInflate() {
RegisterViewBinding binding = DataBindingUtil.bind(this);
RegisterViewModel register = new RegisterViewModel();
binding.setRegister(register);
binding.edPassword.setOnFocusChangeListener(new OnFocusChangeListener(){
@Override public void onFocusChange(View v, boolean hasFocus){
register.updateUsername(edPassword.getText().toString());
}
});

//Similarly for other fields.
}
}

这是我的 View 模型

class RegisterViewModel {
public final ObservableField<String> username = new ObservableField<>();
private final ObservableField<String> password = new ObservableField<>();
private final ObservableField<String> confirmPassword = new ObservableField<>();
public final ObservableBoolean isValid;

//Dependee Observables - isValid depends on all of these
private final ObservableBoolean isUsernameValid = new ObservableBoolean();
private final ObservableBoolean isPasswordValid = new ObservableBoolean();
private final ObservableBoolean arePasswordsSame = new ObservableBoolean();

public RegisterViewModel(){
//Can this binding be made observable so that isValid automatically
//updates whenever isUsernameValid/isPasswordValid/arePasswordsSame change?
isValid = new ObservableBoolean(isUsernameValid.get() &&
isPasswordValid.get() &&
arePasswordsSame.get());

}

public void updateUsername(String name) {
username.set(name);
isUsernameValid.set(ValidationUtils.validateUsername(name));
updateDependents();
}

public void updatePassword(String pwd) {
password.set(pwd);
isPasswordValid.set(ValidationUtils.validatePassword(pwd));
updateDependents();
}

public void updateConfirmPassword(String cnf) {
confirmPassword.set(cnf);
arePasswordsSame.set(password.get().equalsIgnoreCase(cnf.get()));
updateDependents();
}

//Looking to avoid this altogether
private void updateDependents() {
isValid.set(isUsernameValid.get() &&
isPasswordValid.get() &&
arePasswordsSame.get());
}
}

最佳答案

不可能使用 Android 数据绑定(bind)中的绑定(bind)语法对两个 ObservableField 进行数据绑定(bind)。但是,您可以使用代码绑定(bind)它们:

class RegisterViewModel {
public final ObservableField<String> username = new ObservableField<>();
public final ObservableField<String> password = new ObservableField<>();
public final ObservableField<String> confirmPassword = new ObservableField<>();
public final ObservableBoolean isValid = new ObservableBoolean();

private boolean isUsernameValid;
private boolean isPasswordValid;
private boolean arePasswordsSame;

public RegisterViewModel() {
// You can use 3 different callbacks, but I'll use just one here
// with 'if' statements -- it will save allocating 2 Object.
OnPropertyChangedCallback callback = new OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable sender, int propertyId) {
if (sender == username) {
isUsernameValid = ValidationUtils.validateUsername(name);
} else if (sender == password) {
isPasswordValid = ValidationUtils.validatePassword(pwd);
} else if (sender == confirmPassword) {
arePasswordsSame = password.get()
.equalsIgnoreCase(confirmPassword.get());
} else {
// shouldn't get here...
}
isValid.set(isUsernameValid && isPasswordValid && arePasswordsSame);
}
};

username.addOnPropertyChangedCallback(callback);
password.addOnPropertyChangedCallback(callback);
confirmPassword.addOnPropertyChangedCallback(callback);
}
}

在这里,我假设空的用户名、密码和确认密码是无效的。似乎是一个安全的假设。

我没有看到对私有(private) ObservableField 的巨大需求。 ObservableField 被设计为由 UI 绑定(bind),如果不能,您可以使用其他数据类型。如果您发现它们对于使用上述回调的内部绑定(bind)很有用,那就去做吧。

关于android - 是否可以将一个 ObservableField 绑定(bind)到另一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31851551/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com