'Android databinding set padding if value is true

I want to be able to to be able to set padding values if a boolean is true. The problem is that Android studio cannot parse the layout because it thinks 2dp is a decimal with a value of 2 and then doesn't know what to do with the p. how do I format this so that it understands i mean 2 density pixels.

Data layout:

<data class=".ItemBinding">
    <variable name="isGroupType" type="Boolean"/>
</data>

View layout(whats important):

<android.support.v7.widget.AppCompatImageView
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:paddingBottom='@{isGroupType ? 2dp : 0dp}'
            android:paddingTop='@{isGroupType ? 8dp : 0dp}'
            android:paddingRight='@{isGroupType ? 2dp : 0dp}'
            android:paddingLeft='@{isGroupType ? 2dp : 0dp}'/>


Solution 1:[1]

Store padding value in dimen.xml and use it. Please keep habit to write binding string with " " (double quotes)

android:paddingBottom="@{isGroupType ? @dimen/padding_normal : @dimen/padding_null}"

and so on for other paddings also.

Solution 2:[2]

For anyone looking to set margins via DataBinding, you'll have to use BindingAdapter as well:

@BindingAdapter("layoutMarginBottom")
fun setLayoutMarginBottom(view: View, dimen: Float) {
    val layoutParams = view.layoutParams as MarginLayoutParams
    layoutParams.bottomMargin = dimen.toInt()
    view.layoutParams = layoutParams
}

And your xml property will look like this:

app:layoutMarginBottom="@{someCondition ? @dimen/zero_dp : @dimen/twenty_dp}"

Solution 3:[3]

Just as a heads-up this does not work with layout_margin's :(

Not sure why, but think it's due to the parent layout needs to be remeasured..

Solution 4:[4]

@Ravi's answer is correct.

But for more flexibility you can also try this:

@BindingAdapter({"padding", "shouldAdd"})
public static void setPadding(AppCompatImageView imageView, boolean shouldAdd, int padding){
    if (shouldAdd){
        imageView.setPadding(padding, padding, padding, padding);
    }
}

Then:

<android.support.v7.widget.AppCompatImageView
        android:layout_width="64dp"
        android:layout_height="64dp"
        shouldAdd="@{isGroupType}"
        padding="@{10}"/>

Solution 5:[5]

@Ravi's answer is good, but it's working only for padding. If You want to simply add margin, create empty view e.g TextView with padding.

Solution 6:[6]

Use a blank view

<View
android:layout_width = "8dp"
android:layout_height = "8dp"
>

Now constraint this view to the layout you want to control the visibility of . Now disappear this view depending on the condition. would work the same as a margin

Solution 7:[7]

You can use logic and ternary statements in xml-binding, but you really shouldn't. It will come back to haunt you when you're looking the usual places you have logic and don't see what's going on. BindingAdapter for all your margin needs:

fun bindingSetMargins(view: View, start: Float?, top: Float?, end: Float?, bottom: Float?) {
    view.layoutParams = (view.layoutParams as ViewGroup.MarginLayoutParams).apply {
        start?.toInt()?.let { leftMargin = it }
        top?.toInt()?.let { topMargin = it }
        end?.toInt()?.let { rightMargin = it }
        bottom?.toInt()?.let { bottomMargin = it }
    }
}

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 Ravi
Solution 2
Solution 3 ZooMagic
Solution 4 Ayokunle Paul
Solution 5 maatik5
Solution 6 Narendra_Nath
Solution 7 Yokich