I am following this tutorial to learn ViewModel and LiveData. In my case, instead of getting data from network, I am simply generating random string on button click and trying to update a textview. The problem is that the textview does not get updated when the data is changed by button click, but only gets updated when orientation is toggled.
Activity Class (extends LifecycleActivity)
public class PScreen extends BaseActivity {
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.places_screen);
final UserModel viewModel = ViewModelProviders.of(this).get(UserModel.class);
viewModel.init();
viewModel.getUser().observe(this, new Observer<User>() {
@Override public void onChanged(@Nullable User user) {
((TextView) findViewById(R.id.name)).setText(user.getName());
}
});
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
final MutableLiveData<User> data = new MutableLiveData<>();
User user = new User();
user.setName(String.valueOf(Math.random() * 1000));
data.postValue(user);
viewModel.setUser(data); // Why it does not call observe()
}
});
}
}
ViewModel Class
package timsina.prabin.tripoptimizer.model;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModel;
public class UserModel extends ViewModel {
private LiveData<User> user;
public void init() {
if (this.getUser() != null) {
return;
}
this.user = new LiveData<User>() {
@Override protected void setValue(User value) {
value.setName("Fresh New Name");
super.setValue(value);
}
};
}
public LiveData<User> getUser() {
return user;
}
public void setUser(LiveData<User> user) {
this.user = user;
}
}
You are creating a new LiveData instance each time! You are not supposed to do that. If you do that all previous observers will be ignored.
In this case you could replace your setUSer(LiveData<User>) method on your ViewModel to setUser(User u) (taking a User instead of a LiveData) and then do user.setValue(u) inside it.
Of course, will have to initialize the LiveData member in your ViewModel class, like this:
final private LiveData<User> user = new MutableLiveData<>();
It will work then because it will notify the existing observers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With