AndroidMVVM (Architettura)


Osservazioni

Sintassi stranezze con DataBinding

Quando si associa una funzione viewModel a una proprietà in xml, determinati prefissi di funzione come get o is vengono rilasciati. Per esempio. ViewModel::getFormattedText sul ViewModel diventerà @{viewModel.formattedText} quando lo si lega a una proprietà in xml. Analogamente con ViewModel::isContentVisible -> @{viewModel.contentVisible} (notazione Java Bean)

Le classi di bind generate come ActivityMainBinding prendono il nome dal xml per cui stanno creando i collegamenti per, non la classe java.

Binding personalizzati

In activity_main.xml ho impostato l'attributo textColor app e non lo spazio dei nomi di android . Perché? Poiché esiste un setter personalizzato definito per l'attributo textColor che risolve un ID risorsa ColorRes inviato da ViewModel a un colore effettivo.

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);
    }

}

Per i dettagli su come funziona controlla DataBinding Library: Custom Setters

Aspetta ... c'è una logica nel tuo xml !!!?

Si potrebbe argomentare che le cose che faccio in xml per android:visibility e app:textColor sono errate / anti-pattern nel contesto MVVM perché c'è una logica di visualizzazione nella mia vista. Tuttavia, direi che per me è più importante mantenere le dipendenze Android dal mio ViewModel per motivi di test.

Inoltre, cosa fa realmente app:textColor ? Risolve solo un puntatore di risorse per il colore effettivo associato ad esso. Quindi il ViewModel decide ancora quale colore viene mostrato in base ad alcune condizioni.

Per quanto riguarda l' android:visibility che sento a causa di come viene chiamato il metodo, in realtà è ok per usare qui l'operatore ternario. Poiché il nome isLoadingVisible e isContentVisible non vi è alcun dubbio su cosa dovrebbe risolvere ogni risultato nella vista. Quindi ritengo che sia piuttosto l'esecuzione di un comando dato da ViewModel piuttosto che fare una logica di visualizzazione.

D'altra parte sono d'accordo che l'uso di viewModel.isLoading ? View.VISIBLE : View.GONE sarebbe una brutta cosa da fare perché stai facendo delle supposizioni nella vista che cosa significa questo stato per la vista.

Materiale utile

Le seguenti risorse mi hanno aiutato molto nel cercare di capire questo concetto:

MVVM (Architettura) Esempi correlati