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?
3 Réponses :
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)
Ç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
Vous pouvez le faire dans kotlin. Remplacez les accolades par des parenthèses.
btn.setOnClickListener (this::clicklistener) fun clicklistener(v: View){}
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.
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()})
Si vous avez une var onClickListener: OnClickListener
, la même chose que pour les fonctions var
/ val
s'appliquent.
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()}