使用Android架构组件将单向数据绑定转换为双向数据绑定
我正在为一个大学项目重构我的Android应用程序,以使用架构组件,我很难在使用Android架构组件将单向数据绑定转换为双向数据绑定,android,android-databinding,android-architecture-components,android-jetpack,two-way-binding,Android,Android Databinding,Android Architecture Components,Android Jetpack,Two Way Binding,我正在为一个大学项目重构我的Android应用程序,以使用架构组件,我很难在SwitchCompat上实现双向数据绑定。该应用程序有一个简单的用户界面,带有一个显示位置更新状态的TextView,以及前面提到的SwitchCompat,可以切换位置更新的开关。 目前,我在SwitchCompat的选中的属性上使用单向数据绑定,但希望使用。 使用模型-视图-模型体系结构的当前实现如下: MainViewModel.java: public class MainViewModel extends V
SwitchCompat
上实现双向数据绑定。该应用程序有一个简单的用户界面,带有一个显示位置更新状态的TextView
,以及前面提到的SwitchCompat
,可以切换位置更新的开关。目前,我在
SwitchCompat
的选中的属性上使用单向数据绑定,但希望使用。
使用模型-视图-模型体系结构的当前实现如下:
MainViewModel.java:
public class MainViewModel extends ViewModel {
private LiveData<Resource<Location>> mLocationResource;
public MainViewModel() {
mLocationResource = Repository.getInstance().getLocationResource();
}
public LiveData<Resource<Location>> getLocationResource() {
return mLocationResource;
}
public void onCheckedChanged (Context context, boolean isChecked) {
if (isChecked) {
Repository.getInstance().requestLocationUpdates(context);
} else {
Repository.getInstance().removeLocationUpdates(context);
}
}
}
android:onCheckedChanged="@{(buttonView, isChecked) -> viewModel.onCheckedChanged(context, isChecked)}"
android:checked="@{viewModel.getLocationResource}"
现在,android:onCheckedChanged在fragment\u main.xml中实现了:
public class MainViewModel extends ViewModel {
private LiveData<Resource<Location>> mLocationResource;
public MainViewModel() {
mLocationResource = Repository.getInstance().getLocationResource();
}
public LiveData<Resource<Location>> getLocationResource() {
return mLocationResource;
}
public void onCheckedChanged (Context context, boolean isChecked) {
if (isChecked) {
Repository.getInstance().requestLocationUpdates(context);
} else {
Repository.getInstance().removeLocationUpdates(context);
}
}
}
android:onCheckedChanged="@{(buttonView, isChecked) -> viewModel.onCheckedChanged(context, isChecked)}"
android:checked="@{viewModel.getLocationResource}"
最后是要从状态转换为布尔检查状态的自定义绑定适配器:
@BindingAdapter({"android:checked"})
public static void setChecked(CompoundButton view, Resource<Location> locationResource) {
State state = locationResource.getState();
boolean checked;
if (state == State.STOPPED) {
checked = false;
} else {
checked = true;
}
if (view.isChecked() != checked) {
view.setChecked(checked);
}
}
正如我上面链接的《Android开发者指南》所述,我如何才能在Android:checked
中完成所有工作,而不是让Android:checked
和Android:onCheckedChanged
(单向数据绑定到双向数据绑定)?
另外,如果您认为我的应用程序的架构/逻辑可以改进,请告诉我:)以下是我将如何做到这一点(很抱歉Kotlin代码):
首先,我将重构资源
类,并使状态
变量成为MutableLiveData
对象:
enum class State {
LOADING,
UPDATE,
UNKNOWN,
STOPPED
}
class Resource<T>() {
var state = MutableLiveData<State>().apply {
value = State.STOPPED //Setting the initial value to State.STOPPED
}
}
就这样。现在:
- 每当
locationResource.state
更改为state.STOPPED
时,SwitchCompat
按钮将变为未选中状态李>
- 每当
locationResource.state
从state.STOPPED
更改为另一种状态时,SwitchCompat
按钮将变为选中状态李>
- 每当点击
SwitchCompat
按钮并更改为选中状态时,locationResource.state
的值将更改为state.UPDATE
- 每当点击
SwitchCompat
按钮并更改为未选中状态时,locationResource.state
的值将更改为state.STOPPED
如果有什么不清楚的地方,请随时问我。最后,我放弃了从单向数据绑定转换为双向数据绑定的尝试,但我设法简化了一点android:checked
属性:
我取代了价值
"@{viewModel.getLocationResource}"
与
并完全删除了android:checked
@BindingAdapter
你好,Janosch谢谢你的回复。我不明白基于选中状态调用requestLocationUpdates
或removeLocationUpdates
的逻辑在哪里:它不应该在resourceStateAttrChanged
的BindingAdapter
中吗?我将您的应用程序转换为Java,并根据我的需要和假设进行编辑,但我得到了以下信息。(粘贴箱链接)。感谢您的帮助。Hm的setResourceState(CompoundButton视图,int-state)
的状态参数不应该是LocationState
类型的吗,LocationState
是枚举吗?对于public static int getResourceStateAttrChanged(CompoundButton视图)
的返回类型也是如此。错误看起来您仍然在使用函数getLocationResource()
,并且您的mLocationResource
仍然是一个LiveData对象,我建议您删除getLocationResource()
将mLocationResource公开,并将其更改为带有可变LiveData对象state
作为成员变量的资源,就像我回答的第一步一样。另外,在public void onCheckedChanged(CompoundButton-buttonView,boolean-isChecked)方法中,您没有调用attrChange.onChange()
。它通知数据绑定库开关的值已更改。至于在哪里调用requestLocationUpdates或removeLocationUpdates,这是另一个问题,但您的解决方案目前仍有效。嘿,又来了LocationState
是一个包含public static final int
s的类,我在看到后做了这个更改。是的,我仍然在使用getLocationResource()
,因为我不想公开mlLocationResource
,但我宁愿使用getter。另外,我希望保留资源的结构
,而不是将状态
字段设置为可变livedata
。至于缺少的attrChange.onChange()
,是的,它缺少是因为我需要基于选中状态请求/删除,并且因为我不知道双向数据绑定,正如标题所说,我将它扔到了那里。。。。。。如果您可以编辑您的答案,包括原始问题中MainViewModel.java
中的onCheckedChanged
逻辑,那将非常有用
"@{viewModel.getLocationResource}"
"@{viewModel.locationResource.state != State.STOPPED}"