2
votes

Kotlin setOnClickListener utilisant la référence de méthode ne fonctionne pas

J'ai essayé d'utiliser la référence de méthode de la même manière qu'en Java:

button.setOnClickListener {clickListener()}

En utilisant Kotlin:

button.setOnClickListener {this::clickListener}

Mais ce n'est pas le cas fonctionne dans Kotlin, la solution est d'appeler réellement la fonction avec l'expression labmda:

button.setOnClickListener(this::clickListener);

Pourquoi Kotlin n'accepte pas la référence de méthode dans ce cas? N'est-ce pas le même principe qu'avec Java?


0 commentaires

3 Réponses :


5
votes

Les accolades indiquent le contenu de l'expression lambda. Kotlin a déjà passé une instance d'un OnClickListener dans les coulisses et vous fournit la méthode onClick () .

Si vous voulez passer un écouteur que vous avez assigné à une variable, utilisez des parenthèses:

button.setOnClickListener(this::clickListener)

fun clickListener(v: View) {}

Si vous souhaitez utiliser une fonction, c'est la même chose que Java:

button.setOnClickListener(clickListener)


3 commentaires

Ça a du sens. Mais vous proposez d'affecter l'auditeur à une variable, ce qui n'est pas ce que je souhaite. Je veux quelque chose de similaire à Java, en définissant simplement une méthode et en passant simplement la référence à cette méthode avec "this :: method" comme argument au setOnClickListener.


@FraK même syntaxe que Java alors. Passez this :: clickListener entre parenthèses.


Merci. Oui, c'est fondamentalement la même chose, j'ai juste été confondu avec l'expression lambda et la parenthèse supprimée lors de l'utilisation d'une expression lambda dans Kotlin



1
votes

Vous pouvez le faire dans kotlin. Remplacez les accolades par des parenthèses.

btn.setOnClickListener (this::clicklistener)

fun clicklistener(v: View){}


0 commentaires

5
votes

Bien que cela ait déjà été répondu, je voudrais développer les réponses existantes.

Comme TheWanderer l'a déjà mentionné, les accolades signifient ici le corps du lambda. Kotlin prend en charge le placement des rappels en dehors des parenthèses régulières.

This:

button.setOnClickListener(::clickListener);
button.setOnClickListener(this::clickListener);
// alternatively with a different target, if it's somewhere else. 

Est égal à:

button.setOnClickListener(listener)

qui est égal à: p>

val listener = {view: View -> 
       TODO()               
    }

Ou (Java 8 uniquement):

fun clickListener(view: View) { TODO("Place your listener code here") }

TL; DR: contenu des arguments de fonction sont définis avec () , et les corps lambda sont définis avec {} (tout comme avec les fonctions régulières, les classes, les interfaces, etc.).

Maintenant, tout d'abord, un rappel de méthode onClick prend un argument view . Si vous utilisez une fonction autonome, elle doit avoir cet argument:

button.setOnClickListener(view -> clickListener());

Ceci est basé sur la dénomination - si vous implémentez OnClickListener , passez simplement this comme argument. Vous avez déjà l'écouteur et la fonction, vous n'avez donc pas besoin d'en définir explicitement un pour passer. Cependant, si vous implémentez OnClickListener , assurez-vous de vérifier l'ID avant d'agir si vous avez plusieurs vues qui l'utilisent comme écouteur.

Si vous utilisez des méthodes, la suivante dépend de la façon dont.

Utilisation des fonctions var ou val

Si votre rappel est défini comme:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        clickListener();
    }
});

Vous pouvez le passer comme un argument:

button.setOnClickListener({clickListener()})

OnClickListeners h2>

Si vous avez une var onClickListener: OnClickListener , la même chose que pour les fonctions var / val s'appliquent.

Utilisation d'une fonction

Si vous avez un fun clickListener , vous devrez ajouter lambda pour le passer. C'est, tout comme avec Java, en utilisant :: . Cependant, vous n'avez pas besoin de déclarer explicitement la portée comme en Java. Ce qui signifie que l'un ou l'autre fonctionnera:

button.setOnClickListener {clickListener()}

Lectures complémentaires


0 commentaires