Databinding Code Formatting Standards

Variables

If having one-way databinding provide an immutable reference

class FeatureViewModel : ViewModel() {
    private val _name = MutableLiveData("joe")
    val name: LiveData<String>
    get() = _name
}

If any variable can potentially raise an NPE, the compiler will provide a warning describing to unbox the variable
so it is safely treated. Make sure to unbox it or provide a custom data binder adapter which accepts nullables.

android:text="@{safeUnbox(viewModel.name)}"

Here is a custom binding adapter handling a nullable string

@BindingAdapter("safeText")
fun safeText(textView: TextView, value: String?) {
    value?.let {
        textView.text = value
    }
}
app:safeText="@{viewModel.name}"

Databinders should stay away from having logic placed inline as much as possible. Have the ViewModel supply a variable which retains the logic, and is also useful to test.

app:visibleOrGone="@{safeUnbox(viewModel.name.length()==0?false:true)}"

instead

app:visibleOrGone="@{viewModel.isNameAvailable}"

Custom Databinders

@BindingAdapter("editorActionDone")
fun setEditorActionDone(editText: EditText, listener: (() -> Unit)?) {
    listener?.let {
        editText.setOnEditorActionListener { _, actionId, event ->
            if ((event != null && (event.keyCode == KeyEvent.KEYCODE_ENTER)) ||
                (actionId == EditorInfo.IME_ACTION_DONE)) {
                it.invoke()
            }

            false
        }
    }
}
app:editorActionDone="@{viewModel::onNameSubmitted}"
@BindingAdapter(value = [
        "glideSrc",
        "glideErrorHolder",
        "glideCornerRadius",
        "glideTransformation",
        "glideOnLoadStatus"
    ],
    requireAll = false
)
<ImageView
    android:id="@+id/feature_profile_image"
    android:layout_width="@dimen/profile_image_width"
    android:layout_height="wrap_content"
    android:contentDescription="@{viewModel.contentDescription}"
    app:glideSrc="@{viewModel.imgUrl}"/>