'Android ViewModel's LiveData not updating the UI

I have the following fragment:

todays_training_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <import type="android.view.View" />
        <variable
            name="viewmodel"
            type="com.myapp.viewmodel.CurrentTrainingSessionViewModel" />
    </data>

    <LinearLayout
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".fragments.CurrentProgramFragment"
        android:id="@+id/todays_training_fragment"
        >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(viewmodel.activeProgramId)}" />
    </LinearLayout>
</layout>

TodaysTrainingFragment.java

public class TodaysTrainingFragment extends Fragment {
    CurrentTrainingSessionViewModel viewModel;
    private TodaysTrainingFragmentBinding binding;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        binding = DataBindingUtil
                .inflate(inflater, R.layout.todays_training_fragment, container, false);
        binding.setLifecycleOwner(this);

        viewModel =
                ViewModelProviders
                        .of(this)
                        .get(CurrentTrainingSessionViewModel.class);

        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        binding.setViewmodel(viewModel);

        binding.getViewmodel().setActiveProgramId(12342); // <-- I'm expecting the layout to show this value
        binding.setLifecycleOwner(this);
    }
}

CurrentTrainingSessionViewModel.java

public class CurrentTrainingSessionViewModel extends ViewModel {
    private MutableLiveData<Long> activeProgramId = new MutableLiveData<>(0L);



    public long getActiveProgramId() {
        return activeProgramId.getValue();
    }

    public void setActiveProgramId(long id) {
        activeProgramId.postValue(id);
    }

}

I'm expecting my layout to show 0 in the text view as it's the initial value of activeProgramId, and then update the displayed value to 12342 when it's subsequently changed. However, the value stays 0 and doesn't get updated. What am I doing wrong?



Solution 1:[1]

Not sure why you do this twice: binding.setLifecycleOwner(this); Resetting it straight after updating the LiveData in ViewModel may be the culprit, so try removing it from onViewCreated.

Another thing to try is inflating the Databinding without using DataBindingUtil, try this: TodaysTrainingFragmentBinding.inflate(inflater)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1