【问题标题】:How to update UI when data changes in data-binding android?当数据绑定android中的数据发生变化时如何更新UI?
【发布时间】:2020-09-11 17:44:42
【问题描述】:

我有一个显示一个文本视图的活动:

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

    <data>
        <variable
            name="Users"
            type="com.example.mvvm.model.UserInfoModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.MainActivity">

        <TextView
            android:id="@+id/tv_main"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="50dp"
            android:text="@{Users.name,default = hello}"/>

    </LinearLayout>

</layout>

还有我的 UserInfoModel 类:

public class UserInfoModel {
private String name;

public UserInfoModel() {
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}
}

在我的活动中:

public class MainActivity extends AppCompatActivity {

ActivityMainBinding binding;
UserInfoModel users;
TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    
    textView = binding.tvMain;

    users = new UserInfoModel();

    users.setName("Stack");

    viewAction();

    binding.setLifecycleOwner(this);
    binding.setUsers(users);
}
}

我的问题是,当我在 viewAction 方法中更改 name 时:

 private void viewAction() {
    textView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            users.setName("Change Text");
        }
    });
}

我的 UI 没有改变,文本视图仍然显示 Stack。我尝试使用binding.notifyPropertyChanged(id),但它不影响。我的错误在哪里?如何更改数据?

感谢您的关注。

【问题讨论】:

  • 模型更改后是否再次尝试调用 setUsers?
  • @JohnyDeph 有必要吗?它不应该改变生活吗?
  • 只有当你使用下面的答案时它才会改变。或者你需要使用我的方法。此外,最好使用视图模型模式中的实时数据来动态更新 ui))
  • 其实我不喜欢下面的解决方案,因为你的模型变得更脏了
  • @JohnyDeph 能给我看个样本好吗?

标签: android data-binding


【解决方案1】:

您可以让您的字段在模型中可观察。

public class UserInfoModel {
private ObservableField<String> name;

public UserInfoModel() {
 this.name = new ObservableField<>();
}

public ObservableField<String> getName() {
return name;
}

public void setName(String name) {
this.name.set(name);
}
}

【讨论】:

  • 如果我需要几个参数,比如姓名、家庭、工作、电话等……我应该为它们一一定义ObservableField&lt;String&gt;
  • 是的,不要使用字符串,而是使用 ObservableField。这就是库在值更改时知道要观察的字段的方式。
【解决方案2】:

实际上问题是生成的绑定类不知道属性何时更改。你应该通知它。首先,您的视图模型可以从 BaseObservable 类继承,然后您必须将 @Bindable 注释添加到您的视图模型中的 getter 并在设置器中调用 notifyPropertyChanged,并从 BR 类中使用适当的 id(它将由数据绑定库为您生成,只需添加 @可绑定注解。例如 notifyPropertyChanged(BR.name) )。您还应该注意如何在 MainActivity 类中存储“绑定”变量。它可能导致内存泄漏。您可以调查该问题。请参阅 databindingPropertyDelegate 之类的库。

类似的东西

public class UserInfoModel extends BaseObservable{
     @Bindable
     public String getName() {
           return name; 
     } 
     public void setName(String name) {
           this.name = name; 
           notifyPropertyChanged(BR.name)
     }
}

【讨论】:

  • 我认为不需要notifyPropertyChanged。我认为活动 UI 会随着数据的变化而变化。但是,如果我使用 kotlin,如何调用notifyPropertyChanged
  • 这个方法你将从 BaseObservable 类继承。您也可以像@Bilal Aslam 提到的那样使用 ObservableField,甚至可以使用 Livedate 来通知绑定类有关属性更改的信息。其实,看我的例子。它完全符合您的预期。
  • 在 kotlin 中也是一样的。 Getter 必须像这样注释:@get:Bindable(我记得)和 setter 应该调用 notifypropertyChanged
猜你喜欢
  • 2017-11-25
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 2023-02-10
相关资源
最近更新 更多