AndroidMVVM (Архитектура)


замечания

Синтаксические причуды с DataBinding

При привязке функции viewModel к свойству в xml некоторые префиксы функций, такие как get или is , удаляются. Например. ViewModel::getFormattedText в ViewModel станет @{viewModel.formattedText} при привязке его к свойству в xml. Аналогично ViewModel::isContentVisible -> @{viewModel.contentVisible} (нотация Java Bean)

Сгенерированные классы привязки, такие как ActivityMainBinding , называются после xml, для которого они создаются привязки, а не для класса java.

Пользовательские привязки

В файле activity_main.xml я устанавливаю атрибут textColor в app а не пространство имен android . Это почему? Поскольку для атрибута textColor задан пользовательский сеттер, который разрешает идентификатор ресурса ColorRes, отправляемый ViewModel, фактическому цвету.

public class CustomBindings {

    @TargetApi(23)
    @BindingAdapter({"bind:textColor"})
    public static void setTextColor(TextView textView, int colorResId) {
        final Context context = textView.getContext();
        final Resources resources = context.getResources();
        final int apiVersion = Build.VERSION.SDK_INT;
        int color;

        if (apiVersion >= Build.VERSION_CODES.M) {
           color = resources.getColor(colorResId, context.getTheme());
        } else {
            color = resources.getColor(colorResId);
        }

        textView.setTextColor(color);
    }

}

Подробнее о том, как это работает, проверьте библиотеку DataBinding: пользовательские сеттеры

Подождите ... есть логика в вашем xml !!!?

Вы можете утверждать, что то, что я делаю в xml для android:visibility и app:textColor являются неправильными / анти-шаблонами в контексте MVVM, потому что на мой взгляд существует логика представления. Однако я бы сказал, что для меня важнее сохранить зависимости Android от моего ViewModel для тестирования.

Кроме того, что действительно делает app:textColor ? Он разрешает только указатель ressource на фактический цвет, связанный с ним. Таким образом, ViewModel все еще решает, какой цвет отображается на основе какого-либо условия.

Что касается android:visibility я чувствую из-за того, как называется метод, на самом деле это нормально использовать здесь тернарный оператор. Из-за имени isLoadingVisible и isContentVisible действительно нет сомнений в том, что каждый результат должен решить в представлении. Поэтому я чувствую, что это скорее выполнение команды, заданной ViewModel, чем реализация логики представления.

С другой стороны, я согласен с тем, что с помощью viewModel.isLoading ? View.VISIBLE : View.GONE было бы плохо, потому что вы делаете предположения в представлении, что это означает для представления.

Полезный материал

Следующие ресурсы помогли мне в попытке понять эту концепцию:

MVVM (Архитектура) Связанные примеры