This is regarding something quite trivial that I have been fighting over in a code review. The scenario is such. There is a data binding layout:some_layout.xml
, backed by a ViewModel
.
[contents ofsome_layout.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"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View"/>
<variable name="viewModel" type="some.long.package.name.SomeViewModel"/>
</data>
<!-- Other stuffs -->
<TextView
<!-- Other parameters-->>
android:visibility="@{viewModel.someObservableBool?View.VISIBLE : View.GONE}"
/>
</layout>
The requirement, is such I want the TextView
to be View.GONE
(and not View.INVISIBLE
), when the Boolean is false
. The reviewer of my code is insistent of the fact,I should use the Boolean value directly instead of the ternary operator for android:visibility
[android:visibility="@{viewModel.someObservableBool}"
]
Now my understanding is that because of the implicit conversion of the truth values to int will cause the view to be Visible
/Invisible
but not Gone
. As the attrs.xml
definition states the following.
<!-- Controls the initial visibility of the view. -->
<attr name="visibility">
<!-- Visible on screen; the default value. -->
<enum name="visible" value="0" />
<!-- Not displayed, but taken into account during layout (space is left for it). -->
<enum name="invisible" value="1" />
<!-- Completely hidden, as if the view had not been added. -->
<enum name="gone" value="2" />
</attr>
Is my understanding incorrect ?
There is no implicit type conversion in java, and integer values are not interpreted as booleans - it means that if you write
<TextView
<!-- Other parameters-->>
android:visibility="@{viewModel.someObservableBool}"
/>
it just will not compile.
But if you add
@BindingConversion
fun booleanToVisibility(value: Boolean?) = if (value == true)View.VISIBLE else View.GONE
it should work. You can check related docs here