3
votes

Comment faire `onClick ()` en XML appeler deux méthodes?

Je souhaite que onClick () dans ma mise en page xml déclenche deux méthodes à partir de deux modèles de vue.

Code: p >

<Button
    android:onClick="@{() -> model.onButtonClick()}"
    ... />

Le code ci-dessus appelle une méthode, je veux qu'il en appelle une autre à partir d'un autre modèle de vue.
Appel de fonction que je veux ajouter: model2.onButtonClick()

Est-ce possible? Si oui, veuillez ajouter un exemple minimal. ( En attente d'une solution xml )

Remarque: Les modèles de vue sont transmis en tant qu'arguments au format xml. (variables de liaison de données)

Édition 1: Les deux fonctions sont dans deux modèles de vue différents. Donc je sais (après quelques recherches) qu'utiliser / déclarer / initialiser un modèle de vue dans un autre n'est pas une bonne pratique.

Je pourrais créer un écouteur de clic dans mon fragment et y appeler les deux fonctions. Mais je veux éliminer l'écouteur de clic dans les fragments (vues selon MVVM).

Je ne cherche pas de moyen possible. Je recherche une méthode de bonnes pratiques, dans laquelle j'ai l'intention de mettre en œuvre MVVM, la séparation des préoccupations et la liaison de données.


2 commentaires

Pourquoi n'appelez-vous pas la deuxième fonction à l'intérieur en premier?


@EdgarKhimich Veuillez vérifier la question modifiée.


5 Réponses :


1
votes

Vous avez deux options,

  1. Appelez la deuxième méthode dans la première méthode.
fun onClickMethod () {
method1() 
method2() 
} 
fun method1() {
//do stuff  
} 
fun method2() {
//do stuff
} 
  1. Si vous ne souhaitez pas gâcher votre structure de code existante, créez une fonction distincte qui appelle les deux fonctions.
fun method1() {
//do stuff 
method2() 
} 
fun method2() {
//do more stuff
} 


1 commentaires

Vous pouvez essayer de configurer un modèle d'abonné de base, dans lequel les viewmodels souscrivent leur fonction pour être appelée sur un bouton onClick. Je n'ai jamais fait cela auparavant, mais j'ai déjà vu un collègue mettre en place quelque chose de similaire. Je ne sais pas si c'est une bonne pratique ou non. 🤔



0
votes

Dans votre xml, importez deux modèles de vue et passez-les en tant que paramètres dans votre méthode personnalisée qui appellera chaque méthode à partir des modèles de vue.

Je n'ai jamais essayé cela auparavant, mais cela devrait fonctionner. Faites-moi savoir si vous ne comprenez pas


2 commentaires

Ça marche. Mais cela introduit le couplage, que j'essaie d'éliminer.


Pourquoi appelez-vous cela le couplage? Il fera la logique que vous voudrez intégrer



0
votes

Implémentation XML

public void myFancyMethod(View v) {
    // does something very interesting
}

Implémentation de code

   <?xml version="1.0" encoding="utf-8"?>
   <!-- layout elements -->
   <Button android:id="@+id/mybutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click me!"
    android:onClick="myFancyMethod" />
   <!-- even more layout elements -->


1 commentaires

C'est du code pour appeler une seule fonction (que j'ai déjà ajoutée dans ma question), je veux appeler deux fonctions pour un seul clic.



1
votes

J'ai trouvé une solution. Peut-être stupide mais génie dans la simplicité:

app: onRefreshListener = "@ {() -> dashboardVM.onRefresh ()! = homeVM.onRefresh ()}"

La méthode

doit retourner vrai / faux -> peu importe.

Pour tout autre nombre de méthodes, utilisez OR et retournez toujours false.

La solution correcte doit être mise en œuvre via un convertisseur. Mais cela prend beaucoup de code.


0 commentaires

0
votes

En utilisant une fonction d'ordre supérieur, nous pouvons déclencher deux méthodes en même temps

interface ProductInteractionListener {
           fun onItemStateChanged(product: Product, action: () -> Unit)
        }

ProductInteractionListener

  <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <data>
    
            <import type="android.view.View" />
    
            <variable
                name="cartViewModel"
                type="com.rizek.android.users.ui.cart.CartViewModel" />
    
            <variable
                name="product"
                type="com.rizek.android.users.model.productlist.Product" />
    
            <variable
                name="productInteractionListener"
                type="com.rizek.android.users.adapters.recyclerview.cart.ProductListAdapter.ProductInteractionListener" />
        </data>
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                style="@style/text_medium"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:drawablePadding="8dp"
                android:onClick="@{()->
                productInteractionListener.onItemStateChanged(product,cartViewModel.addProduct(product))
                }"
                android:padding="8dp"
                android:text="Add to basket"
                android:textColor="@color/blue"
                android:textSize="14sp"
                app:drawableStartCompat="@drawable/ic_add_circle"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    </layout>


0 commentaires