使用Android体系结构组件将单向数据绑定转换为双向数据

使用Android体系结构组件将单向数据绑定转换为双向数据,第1张

概述我正在重构我的Android应用程序,以便大学项目使用ArchitectureComponents,而我很难在SwitchCompat上实现双向数据绑定.该应用程序有一个简单的用户界面,TextView显示位置更新的状态和前面提到的SwitchCompat,它可以打开和关闭位置更新.目前我在SwitchCompat的checked属性上使用单

我正在重构我的Android应用程序,以便大学项目使用Architecture Components,而我很难在SwitchCompat上实现双向数据绑定.该应用程序有一个简单的用户界面,TextVIEw显示位置更新的状态和前面提到的SwitchCompat,它可以打开和关闭位置更新.
目前我在SwitchCompat的checked属性上使用单向数据绑定,但是想使用two-way databinding.
使用Model-VIEw-viewmodel体系结构的当前实现如下:
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);        }    }}

资源与LT;地点> (看到了想法here)是一个包含可空数据(Location)的类和TextVIEw可以处理的非null状态:
State.java

public enum State {    LOADING,    UPDATE,    UNKNowN,    StopPED}

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

androID:onCheckedChanged="@{(buttonVIEw, isChecked) -> viewmodel.onCheckedChanged(context, isChecked)}"

最后自定义绑定适配器从状态转换为布尔检查状态:

@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.xml中androID:checked属性的实现:

androID:checked="@{viewmodel.getLocationResource}"

正如上面链接的AndroID开发者指南所说,我怎样才能在androID内部完成所有工作:检查而不是同时拥有androID:checked和androID:onCheckedChanged(单向数据绑定到双向数据绑定)?
另外,如果您认为我的应用程序的架构/逻辑可以改进,请告诉我:)

解决方法:

我就是这样做的(抱歉Kotlin代码):

首先,我将重构资源< T> class并使状态变量成为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>()}

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

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

请注意SwitchCompat视图中的双向数据绑定表达式@ =.

现在到BindingAdapter和InverseBindingAdapter:

@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.state从State.StopPED更改为另一个状态时,SwitchCompat按钮将进入选中状态.
>每当轻触Swit​​chCompat按钮并更改为选中状态,则locationResource.state的值将更改为State.UPDATE.
>只要轻触Swit​​chCompat按钮并更改为未选中状态,则locationResource.state的值将更改为State.StopPED.

如果不清楚,请随时问我任何问题.

总结

以上是内存溢出为你收集整理的使用Android体系结构组件将单向数据绑定转换为双向数据全部内容,希望文章能够帮你解决使用Android体系结构组件将单向数据绑定转换为双向数据所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1118562.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存