Как скрыть кнопку в ландшафтном режиме при использовании привязки данных - PullRequest
0 голосов
/ 18 января 2019

У меня есть представление, которое использует DataBinding для отображения данных из ViewModel. Вид имеет кнопку, которая скрыта, когда вид находится в ландшафтном режиме. На данный момент это работает, имея два файла макета, но я хотел бы иметь только один, так как это страшный сон для рефакторинга. Но как это сделать, используя DataBinding и BindingAdapters?

Как включить следующее выражение привязки для данного представления?

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

EDIT:

Определение свойства моего расширения (ViewUtils.kt):

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

И мой макет:

<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}"
            ...
            />

Это вызывает ошибку компиляции: Cause: not a valid name: isLandscapeMode

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Для других, если им нужно такое же поведение. Есть два решения.

Первое решение (создайте BindingAdapter и используйте его на выбранном вами элементе пользовательского интерфейса):

@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
}

В вашем макете XML:

<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"
        ...
        />

Второе решение (создайте выражение связывания, которое изменяет видимость элемента пользовательского интерфейса):

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

Запомните правильный импорт:

<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. Будьте осторожны при использовании привязки данных с AndroidAnnotation . Смотрите выпуск здесь и здесь .

0 голосов
/ 18 января 2019

Вы должны проверить свой адаптер привязки, какая ориентация телефона в настоящее время включена. Вот еще один пост, где вы можете найти ответ на свой вопрос Как определить ориентацию устройства Android?

РЕДАКТИРОВАТЬ:

Вам необходимо определить ориентацию и сохранить ее как логическое значение. Позже вы должны передать эту переменную вашему адаптеру, который в этом случае будет логическим.

<data>

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

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

</data>
...