web-dev-qa-db-fra.com

comment combiner des composants d'architecture avec la liaison de données sur Android?

J'ai développé une base d'applications sur la bibliothèque de liaisons de données Android: https://developer.Android.com/topic/libraries/data-binding/index.html

class SignInViewModel extends BaseObservable {

    @Bindable
    public String getLogin() {
        return login;
    }

    @Bindable
    public String getPassword() {
        return password;
    }
}

et maintenant je veux utiliser ViewModelProviders à partir de la nouvelle bibliothèque: https://developer.Android.com/topic/libraries/architecture/guide.html

SignInViewModel signInViewModel = ViewModelProviders.of(this).get(SignInViewModel.class);

Comment ça se combine? une idée? ou devrait être combiné ces deux bibliothèques?

Modifier

Je change pour: 

class SignInViewModel extends ViewModel {
   public ObservableField<String> login = new ObservableField<>("");

    public ObservableField<String> password = new ObservableField<>("");
}

et maintenant compile, mais la question est: est-ce la bonne façon? 

15
LunaVulpo

C'est une incompatibilité connue. Vous ne pouvez pas étendre BaseObservable et AndroidViewModel en même temps, vous ne pouvez donc pas utiliser @Bindable pour créer une liaison de données bidirectionnelle. impossible*.

Cela sera corrigé après les composants Arch 1.0 final (du côté de la liaison des données).

* Modifier: Vous pouvez créer votre propre ObservableViewModel: https://Gist.github.com/JoseAlcerreca/4b66f9953d50b483d80e6b9ad7172685

15
Jose Alcérreca

Cela n'existait peut-être pas lorsque la question a été posée, mais une autre option est expliquée dans cet article: https://medium.com/google-developers/Android-data-binding-observability-9de4ff3fe038

Fondamentalement, au lieu d'étendre de BaseObservable, vous pouvez implémenter Android.databinding .Observable.

C'est un peu plus de travail que vous devez également faire ce qui suit:

  1. Créer cette variable dans votre classe de modèle

    private PropertyChangeRegistry registry = new PropertyChangeRegistry();
    
  2. Implémenter les méthodes surchargées comme celle-ci

    @Override
    public void addOnPropertyChangedCallback(OnPropertyChangedCallback callback) {
        registry.add(callback);
    }
    
    @Override
    public void removeOnPropertyChangedCallback(OnPropertyChangedCallback callback) {
        registry.remove(callback);
    }
    
  3. Remplacez tous les appels "BR" par ceux-ci:

    registry.notifyChange(this, BR.bar);
    

Tout le reste fonctionne de la même manière que l'extension de BaseObservable. Je pense donc que c’est peut-être la solution à laquelle José aurait pu faire allusion et qui n’était probablement pas disponible à l’époque. Cela semble fonctionner.

Update: Comme Eugene Brusov l'a mentionné, vous pouvez maintenant utiliser LiveData avec la liaison de données. C'est ce que je fais maintenant et c'est beaucoup plus facile avec moins de passe-partout. Voir https://developer.Android.com/topic/libraries/data-binding/architecture .

6
Michael Vescovo

C'est possible avec Android Studio 3.1 Canary 6 ( https://androidstudio.googleblog.com/2017/12/Android-studio-31-canary-6-is-now.html ):

Vous pouvez maintenant utiliser un objet LiveData en tant que champ observable dans les expressions de liaison de données. La classe ViewDataBinding inclut désormais une nouvelle méthode setLifecycle que vous devez utiliser pour observer les objets LiveData.

Vous pouvez trouver plus de détails et des exemples dans cet article Poste moyen .

4
Eugene Brusov

Cela peut également être résolu en utilisant un wrapper:

class SignInViewModelWrapper extends ViewModel {
    public final SignInViewModel model = new SignInViewModel();
}

class SignInViewModel extends BaseObservable {

    @Bindable
    public String getLogin() {
        return login;
    }

    @Bindable
    public String getPassword() {
        return password;
    }
}

Vous pouvez alors obtenir le modèle de vue comme ceci:

SignInViewModel signInViewModel = ViewModelProviders.of(this).get(SignInViewModelWrapper.class).model;
1
user8518198