Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Databinding for inflated layouts in android does not refresh

currently i am developing an app for android and use data binding for my gui.

my problem is that the data that i want to display are not refreshing automatically.

i think the root of my problem is that i inflate multiple sub views into my root view. my view hierarchy looks something like this:

  • layout_activity_main
    • fragment_layout_0 (no data binding here)
    • fragment_layout_1 (layout to display details for a certain device)
      • process_data_view
        • value_0_view
        • value_1_view
        • ...
      • interface_view
      • ...

i use data binding for the process_data_view and value_x_view so that the views are getting refreshed automatically. if a device contains no process data, the process_data_view should be invisible. and until this point it works fine, because the databinding for the device is set up in the onCreateView method of the fragment.

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater,R.layout.layout_details_new,container,false);
        return binding.getRoot();
    }

when there are no process data, the view is invisible and when i receive process data during runtime the view becomes automatically visible.

but now i want to inflate another xml file for the value_x_view. i inflate it like this:

private void setValue(View view, int value){
            ValueViewBinding valueBinding = DataBindingUtil.inflate(getLayoutInflater(null), R.layout.value_view, (LinearLayout)view, false);
            valueBinding.setValue(value)
            View valueView = valueBinding.getRoot();
            ((LinearLayout) view).addView(valueView);
}

*the parameter "view" is a LinearLayout within the parent fragment layout

i inflate about 12 value_views when i run the applikation and they are displayed properly. the only problem is that they are not getting refreshed. they only show the value that was valid when the value_view was inflated.

is there a way to get the data binding working. what do i miss or what am i doing wrong?

like image 440
Tir Avatar asked Dec 24 '22 02:12

Tir


1 Answers

This bit of code:

private void setValue(View view, int value){
    ValueViewBinding valueBinding = DataBindingUtil.inflate(getLayoutInflater(null), R.layout.value_view, (LinearLayout)view, false);
    valueBinding.setValue(value)
    View valueView = valueBinding.getRoot();
    ((LinearLayout) view).addView(valueView);
}

Is a little bit of a problem. The inflation and value setting are being done in the same method. That means that if you want to adjust the value, you'll end up inflating and adding a new View, which I assume you don't want to do.

Perhaps you would prefer to have a ViewStub in your layout instead. Then, when you want to inflate it, you just set it visible. Then the variable assignments are all kept up-to-date without any effort.

<layout ...>
    <data><variable name="value" type="int"/></data>
    <LinearLayout ...>
        <!-- other layouts -->
        <ViewStub android:id="@+id/lateInflation" app:value="@{value}"/>
    </LinearLayout>
</layout>

The other option you have is to add a listener to the binding and whenever the value changes, update the inflated layout yourself. That is more work:

private void setValue(View view, int value){
    final ValueViewBinding valueBinding = DataBindingUtil.inflate(getLayoutInflater(null), R.layout.value_view, (LinearLayout)view, false);
    valueBinding.setValue(value)
    View valueView = valueBinding.getRoot();
    ((LinearLayout) view).addView(valueView);
    // I don't know what your containing
    final LayoutDetailsNewBinding binding = DataBindingUtil.findBinding(view);
    binding.addOnPropertyChangedCallback(new OnPropertyChangedCallback() {
        @Override
        public void onPropertyChanged(Observable sender, int propertyId) {
            // assume the variable name in LayoutDetailsNewBinding is 'value'
            if (propertyId == BR.value) {
                valueBinding.setValue(binding.getValue());
            }
        }
    }
}
like image 141
George Mount Avatar answered Dec 26 '22 17:12

George Mount