2017-12-29 27 views
5

Tôi đang sử dụng kiến ​​trúc Android MVVM với LiveData. Tôi có một đối tượng như thế nàyCập nhật LiveData về thay đổi trường đối tượng

public class User { 
    private String firstName; 
    private String lastName; 

    public String getFirstName() { 
     return firstName; 
    } 

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

    public String getLastName() { 
     return lastName; 
    } 

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

Và mô hình quan điểm của tôi trông như thế này

public class InfoViewModel extends AndroidViewModel { 
    MutableLiveData<User> user = new MutableLiveData<>(); 

    public InfoViewModel(@NonNull Application application) { 
     super(application); 
     User user = new User(); 
     user.setFirstName("Alireza"); 
     user.setLastName("Ahmadi"); 

     this.user.setValue(user); 
    } 

    public LiveData<User> getUser(){ 
     return user; 
    } 

    public void change(){ 
     user.getValue().setFirstName(user.getValue().getFirstName() + " A "); 
    } 
} 

Làm thế nào tôi có thể chắc chắn khi một số đệ trong đối tượng người sử dụng những thay đổi quan sát được thông báo? BTW điều quan trọng với tôi là giữ cho dữ liệu này trong đối tượng riêng biệt và không sử dụng các giá trị chính như Strings trong ViewModel của tôi.

Trả lời

3

Tôi không nghĩ có bất kỳ thực hành tốt nhất như vậy khuyến cáo của android cho việc này. Tôi sẽ đề nghị bạn sử dụng cách tiếp cận sử dụng mã ít hơn boilerplate &.

Nếu bạn đang sử dụng dữ liệu android ràng buộc cùng với LiveData bạn có thể đi với các phương pháp sau đây:

đối tượng POJO của bạn sẽ giống như thế này

public class User extends BaseObservable { 
    private String firstName; 
    private String lastName; 

    @Bindable 
    public String getFirstName() { 
     return firstName; 
    } 

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

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

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

Vì vậy, bạn sẽ đã có một lớp mà thông báo bất cứ khi nào tài sản của nó thay đổi. Vì vậy, bạn chỉ có thể sử dụng tài sản này thay đổi gọi lại trong MutableLiveData của bạn để thông báo cho người quan sát của nó. Bạn có thể tạo một MutableLiveData tùy chỉnh cho điều này

public class CustomMutableLiveData<T extends BaseObservable> 
     extends MutableLiveData<T> { 


    @Override 
    public void setValue(T value) { 
     super.setValue(value); 

     //listen to property changes 
     value.addOnPropertyChangedCallback(callback); 
    } 

    Observable.OnPropertyChangedCallback callback = new Observable.OnPropertyChangedCallback() { 
     @Override 
     public void onPropertyChanged(Observable sender, int propertyId) { 

      //Trigger LiveData observer on change of any property in object 
      setValue(getValue()); 

     } 
    }; 


} 

Sau đó, tất cả các bạn cần làm là sử dụng CustomMutableLiveData này thay vì MutableLiveData trong Xem các mẫu của bạn

public class InfoViewModel extends AndroidViewModel { 

    CustomMutableLiveData<User> user = new CustomMutableLiveData<>(); 
----- 
----- 

Vì vậy, bằng cách làm này bạn có thể thông báo cho cả hai xem & LiveData người quan sát với ít thay đổi đối với mã hiện có. Hy vọng nó sẽ giúp

0

Để người quan sát của bạn được thông báo, bạn nên sử dụng setValue nếu bạn làm điều này user.getValue().setFirstName(user.getValue().getFirstName() + " A "); người quan sát của bạn sẽ không được thông báo!

Xem Mẫu

public MutableLiveData<User> getUser() { 
    return user; 
} 

Hoạt động/Fragment

mModel = ViewModelProviders.of(this).get(InfoViewModel.class); 
mModel.getUser().observe(this, s -> { 
    // User has been modified 
}); 

Một nơi nào đó trong hoạt động của bạn/mảnh

Ðiều này sẽ nhắc người quan sát:

mModel.getUser().setValue(user); 

Nếu bạn wa nt để cập nhật chỉ có một lĩnh vực từ một đối tượng thay vì cập nhật toàn bộ đối tượng bạn nên có bội MutableLiveData<String>

// View Model 
private MutableLiveData<String>   firstName; 
private MutableLiveData<String>   lastName; 

//Somewhere in your code 
mModel.getFirstName().setValue(user.getValue().getFirstName() + " A "); 
mModel.getFirstName().observe(this, s -> { 
    // Firstname has been modified 
}); 
Các vấn đề liên quan