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.
5 Réponses :
Vous avez deux options,
fun onClickMethod () { method1() method2() } fun method1() { //do stuff } fun method2() { //do stuff }
fun method1() { //do stuff method2() } fun method2() { //do more stuff }
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. 🤔
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
Ç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
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 -->
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.
J'ai trouvé une solution. Peut-être stupide mais génie dans la simplicité:
app: onRefreshListener = "@ {() -> dashboardVM.onRefresh ()! = homeVM.onRefresh ()}"
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.
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>
Pourquoi n'appelez-vous pas la deuxième fonction à l'intérieur en premier?
@EdgarKhimich Veuillez vérifier la question modifiée.