0

I have a view that uses DataBinding to display data from a ViewModel. The view has a button that is hidden when the view is in landscape mode. At the moment this works by having two layoutfiles, but I would like to only have one as it's a nightmare to refactor. But how to go about this using DataBinding and BindingAdapters?

How do you enable the following bindingexpression for a given view?

android:visibility="@{isLandscapeMode ? View.INVISIBLE : View.VISIBLE}"

EDIT:

My extension property definition (ViewUtils.kt):

val View.isLandscapeMode: Boolean
    get() = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE

And my layout:

<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"/>
        <import type="com.example.base.views.ViewUtilsKt" />
        <variable
            name="isLandscapeMode "
            type="java.lang.Boolean"/>
        <variable
            name="viewmodel"
            type="com.example.ui.task.TaskViewModel" />
    </data>

    ...

    <ImageButton
            ...
            android:visibility="@{isLandscapeMode ? View.INVISIBLE : View.VISIBLE}"
            ...
            />

This causes a compile error: Cause: not a valid name: isLandscapeMode

Bohsen
  • 4,242
  • 4
  • 32
  • 58

2 Answers2

1

You have to check in your binding adapter which phone orientation is currently on. Here is another post where you can find answer to your question how to detect orientation of android device?

EDIT:

You need to detect orientation and save it as boolean value. Later you have to pass that variable to your adapter which in this case will be boolean.

<data>

<import type="android.view.View"/>

<variable
    name="isLandscapeMode"
    type="boolean"/>

</data>
Bohsen
  • 4,242
  • 4
  • 32
  • 58
DawidJ
  • 1,245
  • 12
  • 19
  • I know how to detect orientation. The question relates to how the bindingexpression is enabled. ie. how are you able to do `android:visibility="@{isLandscapeMode ? View.INVISIBLE : View.VISIBLE}"` – Bohsen Jan 18 '19 at 11:55
  • You should include that information in original question. I have edited my answer – DawidJ Jan 18 '19 at 12:01
  • If only the view would render correctly. It keeps showing the button I'm trying to hide :( – Bohsen Jan 21 '19 at 13:22
  • Should we use a boolean variable or `MutableLiveData`? – CoolMind Jun 22 '21 at 07:30
0

For others if they need same behavior. There are two solutions.

First solution (create a BindingAdapter and use it on the UI element of your choice):

@BindingAdapter("bind:visibleInLandscapeMode")
fun View.setVisibleInLandscapeMode(visible: Boolean) {
    Timber.d("setVisibleInLandscapeMode() returns ${resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE}")
    visibility = if (visible && (resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE)) VISIBLE else INVISIBLE
}

In your XML layout:

<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"
    xmlns:bind="http://schemas.android.com/apk/lib/com.example">

    ...

    <ImageButton
        ...
        bind:visibleInLandscapeMode="false"
        ...
        />

Second solution (create a bindingexpression that changes the visibility of the UI element):

<ImageButton
    ...
    android:visibility="@{context.getResources.getConfiguration.orientation == Configuration.ORIENTATION_LANDSCAPE ? View.INVISIBLE : View.VISIBLE}"
    ...
    />

Remember the correct imports:

<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"/>
        <import type="android.content.res.Resources" />
        <import type="android.content.res.Configuration" />
        ...
    </data>
    ...

Btw. be careful when using Databinding with AndroidAnnotation. See issue here and here.

Bohsen
  • 4,242
  • 4
  • 32
  • 58