Reputation: 491
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
Reputation: 131
While using Data Binding, you should take care of two things.
binding.vm = yourViewModel
(Note: vm
is a variable name that you defined under layout tag.)
binding.lifecycleOwner = this
Upvotes: 0
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
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