[英]Two-way data binding for android:enabled attribute
我想弄清楚Android中的双向数据绑定库。 我想通过更改xml中的android:enabled属性来启用/禁用LinearLayout(和里面的RelativeLayout)。
XML部分如下所示:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_margin="5dp"
android:gravity="center"
android:enabled="@={viewModel.asd}"
ndroid:onClick="@{()-> viewModel.doSomething()}"
android:background="@drawable/shortcut_button_label_selector"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="40dp"
android:layout_height="match_parent"
android:enabled="@={viewModel.asd}"
android:background="@drawable/shortcut_button_icon_selector">
现在,我想要这样做的原因是因为这两个选择器(shortcut_button_label_selector和shortcut_button_icon_selector),它们看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="false"
android:drawable="@color/grey_300"></item>
<item
android:state_enabled="true"
android:drawable="@color/menubar_background"></item>
</selector>
我希望能够根据View上的enabled属性动态更改背景。 我选择enabled属性的原因是我在LinearLayout上得到了onClick事件,我需要禁用它(使其无法点击); 我对android:clickable属性有同样的问题。
事情是当我尝试编译它时,我收到了错误
java.lang.RuntimeException:发现数据绑定错误。 **** /数据绑定错误****消息:在android.widget.LinearLayout上找不到属性'android:enabled'的getter,其值类型为boolean。
viewModel.asd只是一个公共boolean / ObservableBoolean,我试过了。
任何人都可以解释发生了什么,为什么我得到错误? 我可以在View类中看到isEnabled / setEnabled方法(Layouts扩展)。
有什么方法可以继续我的方法或我必须完全改变它?
//编辑:我可能不需要双向绑定..我不知道 //编辑继续:它可能需要对我的ViewModel继承做一些事情:
布局文件有一个类型为abMainViewModel的viewModel,但字段asd是abBaseViewModel中的int(MainViewModel扩展了BaseViewModel)。 现在我想要的是如果我从扩展BaseViewModel的任何其他视图更新asd字段,它会自动更新enabled属性。
它也不适用于Strings ..我猜它是继承的东西
亲切的问候,Marcin
您的错误可能有多种原因。 首先,双向数据绑定不适用于android:enabled
属性。 这是因为没有回调来告诉数据绑定属性已更改。
双向数据绑定适用于用户输入数据的大多数属性,因此最简单的方法是将数据视为从用户获取数据到模型。
您可能收到类似错误的另一个原因是模型可能没有可绑定属性。 您应该使用Observable:
public class ViewModel extends BaseObservable {
private boolean asd = true;
@Bindable
public boolean getAsd() { return asd; }
public void setAsd(boolean asd) {
this.asd = asd;
notifyPropertyChanged(this, BR.asd);
}
}
或使用ObservableFields:
public class ViewModel {
public final ObservableBoolean asd = new ObservableField(true);
}
如果没有这个,单向数据绑定只会在第一次工作 - 如果更改ViewModel,UI将不会更新。
您似乎不需要为android:enabled
属性进行双向数据绑定。 一种方式数据应该可以正常工作来改变选择器的状态。
所以,我试图缩小问题的原因并且只有在我将编辑添加到我以前的帖子后才意识到它可能确实存在继承问题。
基本上,我所拥有的是主Activity的绑定(称为MainActivity)和在该活动内被替换的片段的单独绑定。 两个绑定的视图模型都在扩展保存该布尔值的BaseViewModel。 主活动绑定必须在每个片段更新时更新(假设我必须隐藏/显示某些东西,具体取决于我实际所在的片段)。
现在,我希望发生的是,如果我在MainActivityViewModel设置布尔(即实际上会在基类中设置的值和替换“即”扩大在其他领域的视图模型底座前将更新...我傻,我意识到我必须直接更新MainViewModel中的布尔值。这是基本的Java概念,与Android没有任何关系。
但是,我不知道如何解释的一件事是,这个布尔值是从java.util.Set#contains方法返回的。 我有一个ObservableField observableSet (现在在MainViewModel中)和方法isInTheSet(Object)返回set.contains(Object) 。
当我在xml文件( viewModel.isInTheSet(Object) )中执行该方法时,它在我更改ObservableField值时没有更新视图。 但是,当我更改xml以使用viewModel.observableSet.contains(Object)时,它工作..任何人都可以解释这个吗?
很抱歉在这里造成了大规模的混乱,昨天我在工作中度过了漫长的一天。
//编辑:是的,我不需要双向绑定..
马尔钦
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.