【问题标题】:Bindable not getting notified可绑定未收到通知
【发布时间】:2018-07-03 10:49:15
【问题描述】:
@Bindable
public String getFirstName() { 
    return this.firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
    notifyPropertyChanged(BR.firstName);
}

@Bindable
public String getLastName() { 
    return this.lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
    notifyPropertyChanged(BR.lastName);
}


@Bindable({"firstName", "lastName"})
public void getName() { 
    return this.firstName + ' ' + this.lastName; 
}

以上代码是我从 Google 的示例代码中提取的 - https://developer.android.com/reference/android/databinding/Bindable

并在 XML 中使用它

<TextView
    android:id="@+id/first_name"
    .....
    android:text="@{myViewModel.firstName}" />
<TextView
    android:id="@+id/last_name"
    .....
    android:text="@{myViewModel.lastName}" />
<TextView
    android:id="@+id/full_name"
    .....
    android:text="@{myViewModel.getName()}" />

每当我打电话给myViewModel.setFirstName("Mohammed"); 时,它都会更新视图中的名字,而不是全名。甚至文档都是错误的,不可靠。

与此问题相关的其他帖子无济于事,因为它们中的大多数都涉及非参数化的 Bindables。

根据文档中的这一行

只要 firstName 或 lastName 有更改通知,name 也将被视为脏。这并不意味着 BR.name 会通知 onPropertyChanged(Observable, int),只是包含 name 的绑定表达式会被弄脏和刷新。

我也尝试调用notifyPropertyChanged(BR.name);,但对结果也没有影响。

【问题讨论】:

    标签: android android-databinding bindable


    【解决方案1】:

    只是一个小技巧

    public class Modal {
        private String firstName;
        private String lastName;
        private String name;
    
        @Bindable
        public String getFirstName() {
            return this.firstName;
        }
    
        public void setFirstName(String firstName) {
            this.firstName = firstName;
            notifyPropertyChanged(BR.firstName);
            notifyPropertyChanged(BR.name);
        }
    
        @Bindable
        public String getLastName() {
            return this.lastName;
        }
    
        public void setLastName(String lastName) {
            this.lastName = lastName;
            notifyPropertyChanged(BR.lastName);
            notifyPropertyChanged(BR.name);
        }
    
    
        @Bindable
        public void getName() {
            return this.firstName + ' ' + this.lastName;
        }
    }
    

    【讨论】:

    • 很抱歉破坏了派对,但我找到了实际的解决方案。他们的文档很糟糕。为了理解这个数据绑定的概念,不得不打破头脑。
    • 如果您已经在代码中的任何地方使用此 hack,那么我建议您查看我的答案。虽然这是一个很好的工作技巧,但我设法找到了实际的解决方案。
    【解决方案2】:

    所以在彻底分析数据绑定概念后,我发现当我们在 BaseObservable 类上调用 notifyPropertyChanged 时,它实际上通知了属性,而不是 getter 和 setter。

    所以在我上面的问题中,JAVA部分没有变化,但是XML部分需要改变。

    <TextView
        android:id="@+id/first_name"
        .....
        android:text="@{myViewModel.firstName}" />
    <TextView
        android:id="@+id/last_name"
        .....
        android:text="@{myViewModel.lastName}" />
    <TextView
        android:id="@+id/full_name"
        .....
        android:text="@{myViewModel.name}" />
    

    由于我将getName() 声明为Bindable({"firstName", "lastName"}),因此数据绑定会生成属性name,因此我必须在我的XML 中侦听myViewModel.name 而不是myViewModel.getName()。我们甚至不必通知name 进行更改,只通知firstNamelastName 将通知属性name,因为参数化了Bindable。

    但要确保

    【讨论】:

    • 酷,顺便说一句,我没有注意到你正在使用myViewModel.getName()。绑定不使用方法名称语法,它会找到名称访问器。所以总是使用字段名称。
    • 这是任何人都不会注意到的最后一件事,即使是文档也不清楚。但是如果我们正在监听属性,那么只有参数化的 Bindables 就可以完成这项工作。
    猜你喜欢
    • 1970-01-01
    • 2021-10-30
    • 2014-05-21
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多