gpt4 book ai didi

android - 使用 Android 架构组件将单向数据绑定(bind)转换为双向数据绑定(bind)

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:10:28 24 4
gpt4 key购买 nike

我正在为一个大学项目重构我的 Android 应用程序以使用架构组件,但我很难在 SwitchCompat 上实现双向数据绑定(bind)。该应用有一个简单的用户界面,其中包含一个显示位置更新状态的 TextView 和前面提到的用于打开和关闭位置更新的 SwitchCompat
现在我在 SwitchCompatchecked 属性上使用单向数据绑定(bind),但我想使用 two-way databinding .
当前使用模型- View - View 模型架构的实现如下:
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);
}
}
}

Resource (看到 here 的想法)是一个包含可为空数据(Location)和 TextView 可以处理的非空状态的类:
State.java

public enum State {
LOADING,
UPDATE,
UNKNOWN,
STOPPED
}

现在fragment_main.xml中的android:onCheckedChanged实现:

android:onCheckedChanged="@{(buttonView, isChecked) -> viewModel.onCheckedChanged(context, isChecked)}"

最后是自定义绑定(bind)适配器,用于将状态转换为 bool 检查状态:

@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);
}
}

以及fragment_main.xmlandroid:checked属性的实现:

android:checked="@{viewModel.getLocationResource}"

正如我上面链接的 Android 开发者指南所说,我如何在 android:checked 中完成所有工作,而不是同时拥有 android:checkedandroid :onCheckedChanged(单向数据绑定(bind)到双向数据绑定(bind))?
另外,如果您认为我的应用程序的架构/逻辑可以改进,请告诉我:)

最佳答案

以下是我的做法(对 Kotlin 代码感到抱歉):

首先我会重构 Resource<T>上课并制作state变量a MutableLiveData<State>对象:

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
}
}

然后我将创建以下 ViewModel:

class MainViewModel: ViewModel() {

val locationResource = Resource<Location>()

}

在数据绑定(bind)布局中,我将编写以下内容:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

<variable
name="viewModel"
type="MainViewModel" />

</data>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<androidx.appcompat.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:resourceState="@={viewModel.locationResource.state}" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(viewModel.locationResource.state)}" />

</LinearLayout>

</layout>

注意双向数据绑定(bind)表达式 @=SwitchCompat查看。

现在到 BindingAdapterInverseBindingAdapter :

@BindingAdapter("resourceState")
fun setResourceState(compoundButton: CompoundButton, resourceState: State) {
compoundButton.isChecked = when (resourceState) {
// You can decide yourself how the mapping should look like:
State.LOADING -> true
State.UPDATE -> true
State.UNKNOWN -> true
State.STOPPED -> false
}
}

@InverseBindingAdapter(attribute = "resourceState", event = "resourceStateAttrChanged")
fun getResourceStateAttrChanged(compoundButton: CompoundButton): State =
// You can decide yourself how the mapping should look like:
if (compoundButton.isChecked) State.UPDATE else State.STOPPED

@BindingAdapter("resourceStateAttrChanged")
fun setResourceStateAttrChanged(
compoundButton: CompoundButton,
attrChange: InverseBindingListener
) {
compoundButton.setOnCheckedChangeListener { _, isChecked ->
attrChange.onChange()

// Not the best place to put this, but it will work for now:
if (isChecked) {
Repository.getInstance().requestLocationUpdates(context);
} else {
Repository.getInstance().removeLocationUpdates(context);
}
}
}

就是这样。现在:

  • 每当locationResource.state更改为 State.STOPPED , SwitchCompat按钮将进入未选中状态。
  • 每当locationResource.stateState.STOPPED 更改到另一个州,SwitchCompat按钮将进入选中状态。
  • 每当 SwitchCompat点击按钮并更改为选中状态然后 locationResource.state 的值将更改为 State.UPDATE .
  • 每当 SwitchCompat点击按钮并更改为未选中状态然后 locationResource.state 的值将更改为 State.STOPPED .

如果有什么不清楚的地方,请随时问我。

关于android - 使用 Android 架构组件将单向数据绑定(bind)转换为双向数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54506398/

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