Можно ли условно отобразить включение XML на основе ответа метода classes?

#android #xml #android-databinding

#Android #xml #android-привязка данных

Вопрос:

Мне интересно, можно ли использовать привязку данных для условного отображения макета на основе логического ответа методов. Вот что я пытаюсь сделать

Макет XML:

 <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable
            name="View"
            type="android.view.View"/>

        <variable
            name="App"
            type="com.app.JTApp"/>
    </data>

    <include layout="@layout/view_checkout_total_cardview"
             android:visibility="@{App.isLandscape() ? View.GONE : View.VISIBLE}" />

</layout>
  

Класс JTApp:

 public class JTApp {

    public boolean isLandscape() {
        Timber.d("putty-- isLandscape: --------------------------");
        return getResources().getBoolean(R.bool.is_landscape);
    }

    …
}
  

В настоящее время это не работает. Я что-то упускаю или это невозможно? Я пришел из Интернета, где это возможно с помощью таких фреймворков, как Angular.

Комментарии:

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

2. Это то, что я делаю до тех пор, пока не найду решение, которое не требует создания дополнительных файлов.

3. Я не замечаю ничего плохого в вашем коде, вы получаете какие-либо ошибки? Вызывается isLandscape() ли вызов? Вы правильно связываете View и JTApp в своем Activity ?

4. isLandscape не вызывается, и я попытался импортировать переменную vs setting на основе вашего ответа, но она по-прежнему не работает.

Ответ №1:

Да, возможно использование условного оператора в XML. Я не слишком знаком с библиотекой привязки данных, но в документации используется аналогичная функциональность:

Внутри элемента данных может использоваться ноль или более элементов импорта. Это позволяет легко ссылаться на классы внутри вашего файла макета, как в Java.

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

Теперь View может использоваться в вашем выражении привязки:

 <TextView
   android:text="@{user.lastName}"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"/>
  

Я считаю, что единственная проблема с вашим кодом заключается в том, что вы используете View as a variable вместо as an import в своем <data> элементе.

Комментарии:

1. Эти переменные ссылаются, но ничего не говорят об использовании методов для проверки. Я знаю, что могу автоматически добавить переменную isLandscape в приложение, но это кажется излишним для моего варианта использования, просматриваемого в конфигурации.

2. @MariusMiliunas Вам нужно следить за изменениями конфигурации? Почему бы просто не позволить Activity воссоздать, затем данные должны быть повторно привязаны и проверить isLandscape() еще раз, нет? Я не тестировал это, но я не понимаю, почему это не сработает.

3. @MariusMiliunas Ах, я понимаю, что вы говорите о проверке метода. Сначала пропустил это. Если вы не можете использовать метод, почему бы просто не привязать Boolean значение вместо JTApp класса? Затем просто используйте binding.setBoolean(JTApp.isLandscape()) .

4. Я не могу сделать JTApp привязкой, потому что это корневой экземпляр приложения, и это нарушит многие другие вещи. Кроме того, я не могу использовать привязку данных в этом представлении, используя текущую активность, потому что наше приложение было построено на глубоко унаследованных родительских действиях, которые устанавливают представление содержимого глубоко внизу. Он не был создан с учетом базы данных, поэтому здесь я пытался выяснить, возможно ли ссылаться на случайные пакеты, которые обладают нужной мне функциональностью, которые также не созданы с учетом привязки данных.

5. @MariusMiliunas Если вы не используете привязку данных к текущему Activity , с чем вы его используете? Кроме того, я не понимаю, как использование метода из вашего Application класса нарушит другие вещи. Если isLandscape() это уже метод, почему вы не можете использовать его в других случаях?

Ответ №2:

Вы можете сделать это проще с помощью модификаторов ресурсов:

  • есть один макет в layout-land, который не содержит cardview
  • есть другой макет в layout, который содержит cardview

таким образом, вы получите этот эффект, и в ландшафте он даже не будет увеличен, а затем станет невидимым

Комментарии:

1. Хотя я согласен, что это более простой метод достижения того же результата, я не думаю, что он отвечает на вопрос. Вопрос заключается в том, возможно ли это, а не в том, является ли это лучшим способом. Это также было рассмотрено в комментарии @cricket_007.

2. Согласен — но я не думаю, что лучше показать правильный путь для его проблемы, чем правильный ответ на его вопрос (что было бы неправильным способом)

3. Без обид, но вы не знаете контекста моей ситуации.

4. Да, я знаю только контекст, который вы указали в своем вопросе