mantc_sdr
mantc_sdr

Reputation: 491

android two-way Data Binding - data changes does not update UI views

I am using android two-way data binding, but data changes does not update view elements. I have a simple string correctly displayed on an TextInputEditText, but when the bound viewmodel livedata variable is updated, the view is not updating. The variable info is supposed to show 'Hello my friend' on the radiobutton click listener..but it is not updating the ui.

fragment:

public class MainFragment extends Fragment {

private MainViewModel mViewModel;
private MainFragmentBinding mDataBinding;

public static MainFragment newInstance() {
    return new MainFragment();
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                         @Nullable Bundle savedInstanceState) {
    mDataBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.main_fragment, container, false);
    return mDataBinding.getRoot();
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mViewModel = new ViewModelProvider(this).get(MainViewModel.class);

    mViewModel.getInfo().observe(getViewLifecycleOwner(), info -> {
        Toast.makeText(getActivity().getApplicationContext(), "First in", Toast.LENGTH_SHORT).show();

    });

    mDataBinding.radioButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mViewModel.getInfo().setValue("Hello my friend");
        }
    });

    mDataBinding.setViewModel(mViewModel);
}
}

viewmodel:

public class MainViewModel extends ViewModel {

private MutableLiveData<String> info;

public MutableLiveData<String> getInfo() {
    if (info == null) {
        info = new MutableLiveData<>();
        info.setValue("First Info Initialization");
    }

    return info;
}

public void setInfo(String info) {
    this.info.setValue(info);
}

and view is something like:

    <layout>...
    <data>

        <variable
        name="viewModel"
        type="com.example.temp.ui.main.MainViewModel" />
    </data>

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/info"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Info"
            android:text="@={viewModel.info}" />
    </com.google.android.material.textfield.TextInputLayout>
    </layout>

Upvotes: 0

Views: 1649

Answers (3)

Shubham
Shubham

Reputation: 131

While using Data Binding, you should take care of two things.

  1. Assign ViewModel to a variable that is defined under your layout tag in the xml:
binding.vm = yourViewModel

(Note: vm is a variable name that you defined under layout tag.)

  1. Most important, provide lifecycleOwner to your binding class:
binding.lifecycleOwner = this

Upvotes: 0

AndroidSam27
AndroidSam27

Reputation: 296

To use a LiveData object with your binding class, you need to specify a lifecycle owner to define the scope of the LiveData object.

// Specify the current activity as the lifecycle owner.
    binding.setLifecycleOwner(this);

Upvotes: 1

mantc_sdr
mantc_sdr

Reputation: 491

The binding lifecycle owner was the Activity hosting the fragment:

MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
binding.setLifecycleOwner(this);

Then I had to remove it and set the Fragment as the lifecycle owner.

Upvotes: 0

Related Questions