简体   繁体   中英

How to update UI when data changes in data-binding android?

I have an activity that shows one text-view in that:

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

And my UserInfoModel class:

public class UserInfoModel {
private String name;

public UserInfoModel() {
}

public String getName() {
    return name;
}

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

And in my Activity:

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

My Problem is, When I Change name in viewAction method like this:

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

My UI doesn't change and text-view still showing Stack . I try to use binding.notifyPropertyChanged(id) but it doesn't affect. Where is my mistake? How can I change the data?

thanks for your attention.

Actually the problem is that generated binding class doesn't know when property is changed. You should notify it. First, your viewmodel can be inherited from BaseObservable class, then you have to add @Bindable annotation to getters in your viewmodel and call notifyPropertyChanged inside setters with appropriate id from BR class(it's going to be generated for you by databinding library, just add @Bindable annotation. for instance notifyPropertyChanged(BR.name) ). Also you should pay attention how you store "binding" variable in MainActivity class.It can lead to memory leaks. You can investigate that issue. See library like databindingPropertyDelegate.

Something like this

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

You can just make your fields observable in the models.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM