I have a class named MyInfoModel
that has some instance variables in it to store data about the user and a method to notify the observers of the class.
private final List<ObserverInterface> observers = new ArrayList<>();
private int id;
private String name;
private String imageURL;
// Getters, Setters, Register and Unregister Methods for Instance Variables
// Also All Setter Methods call the notifyObservers() method after setting the values
private void notifyObservers(){
Log.d(this.getClass().getName(), "Notifying All Observers");
for (ObserverInterface observer : observers){
observer.updateViews();
}
}
I have an interface ObserverInterface
that has only one method void updateViews();
which is overridden by other classes that implement this interface.
I am using Retrofit to request some data which gets updated in a static object in the Constants class.
public class Constants {
public static MyInfoModel INFO_CONSTANTS = new MyInfoModel();
}
Also, I have a View Model MainActivityViewModel
that extends ViewModel
class and has variables, getters and setters to support the layout of the activity.
private int id;
private String name;
private String imageURL;
// Getters and Setters
I have used DataBinding in my layout like this
<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="viewModel"
type="com.itsyourap.app.viewModel.MainActivityViewModel" />
</data>
<TextView <!-- Layout Tags -->
android:text="@{viewModel.Name}" />
Then I have the MainActivity
where I want to wait for any change in the values of variables of Constants.INFO_CONSTANTS
, so I implement the ObserverInterface
interface and Override the updateViews()
method like this:-
public class MainActivity extends AppCompatActivity implements ObserverInterface {
private MainViewModel mainViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
mainViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class);
mainBinding.setViewModel(mainViewModel);
mainBinding.getViewModel().setName("Alpha Beta Gamma"); // Works
mainBinding.getViewModel().setImageURL("somelink.jpg"); // Works
}
public MainActivity(){
Constants.INFO_CONSTANTS.register(this);
}
@Override
public void updateViews() {
if (mainViewModel != null){
Log.d(this.getClass().getName(), "Updating Views");
mainViewModel.setName(Constants.INFO_CONSTANTS.getName()); // Does Not Work
mainViewModel.setImageURL(Constants.INFO_CONSTANTS.getImageURL()); // Does Not Work
}
}
}
The problem I am facing that the updateViews()
is called successfully (according to LogCat) but the Layout isn't updated at the runtime. I have tried using LiveData
and MutableLiveData
but they do not seem to work as well. Also I tried using mainBinding.setLifecycleOwner(this);
but it didn't work as well.
Also calling the setters from the onCreate()
method works perfectly but does not work from the updateViews()
method.
How should I make it work? I just want the values in the layout to change as soon as the values in the ViewModel gets changed.
Thanks in Advance
Calling setViewModel()
after modifying the variables solves the issue
@Override
public void updateViews() {
if (mainViewModel != null){
Log.d(this.getClass().getName(), "Updating Views");
mainViewModel.setName(Constants.INFO_CONSTANTS.getName());
mainViewModel.setImageURL(Constants.INFO_CONSTANTS.getImageURL());
mainBinding.setViewModel(mainViewModel); // Solves The Problem
}
}