38

I've been trying to set up a long click listener event, but keep getting the following error:

Type mismatch. 

Required:Boolean

Found:Unit

I've had no issues with the setOnClickListener event, but for some reason I'm having zero luck with the setOnLongClickListener event.

I'm currently trying to display a simple Toast:

view.setOnLongClickListener{
    Toast.makeText(this, "Long click detected", Toast.LENGTH_SHORT).show();
}

I've seen plenty of examples for Java, but I'm yet to find any examples for Kotlin.

stkent
  • 18,470
  • 14
  • 80
  • 99
Dylan Hargett
  • 383
  • 1
  • 3
  • 4

5 Answers5

98

OnLongClickListener.onLongClick signature required that you return a boolean to notify if you actually consumed the event

view.setOnLongClickListener{
     Toast.makeText(this, "Long click detected", Toast.LENGTH_SHORT).show()
     return@setOnLongClickListener true
}

or

view.setOnLongClickListener{
     Toast.makeText(this, "Long click detected", Toast.LENGTH_SHORT).show()
     true
}
Samuel Eminet
  • 3,898
  • 13
  • 30
  • Great Answer We would like to add one thought as you try to construct this the compiler complains IF the return or true statement is not added before any other lines of code between the opening an closing which to the beginner or novice will believe what is being entered is wrong Just a thought – Vector Sep 20 '18 at 05:09
  • Thanke you Samuel – RKRK Oct 18 '18 at 14:56
  • Remember that you can access the view passed by the listener by using the "it" variable inside the Kotlin function – Luis Cabrera Benito Oct 15 '19 at 18:27
  • For me it was marking my if/else structure in red, so I thought I didn't write a proper comparison. That was really confusing for a while, spent 20min retyping my brackets to make sure they were correct (they were). – The Fox Nov 04 '19 at 20:23
1

Another way can be this...

view.setOnLongClickListener{
    dispathAnEventOnLongClick("Long click detected!");
}
private fun dispathAnEventOnLongClick(text:CharSequence): Boolean {
    Toast.makeText(applicationContext,text,Toast.LENGTH_SHORT).show();
    return true;
}
1

Inline Functions

You can make an inline function that consume a function and return a boolean. Then use it with any functions that required a boolean as return type.

In a kotlin file:

inline fun consume(function: () -> Unit): Boolean {
    function()
    return true
}

Usage:

view.setOnLongClickListener {
   consume { Toast.makeText(context, "Long click detected", Toast.LENGTH_SHORT).show() }
}

Now your code will work and returned a true value to satisfied the need for setOnLongClickListener method. You can reuse this function consume with any function that require a true value like onCreateOptionsMenu and onOptionsItemSelected without an explicitly needs to return a true value.

This way uses: Inline Functions. And the solution you checked as a best answer uses : Labeled Return.

MohammadL
  • 2,096
  • 16
  • 31
1

I did like this.

Inside onCreate,

    findViewById<Button>(R.id.myButton).setOnLongClickListener(myButtonLongClickListener)

And then,

private var timeButtonLongClickListener = View.OnLongClickListener {
    true
}
Water
  • 331
  • 4
  • 5
0

This one also works for Kotlin. Simply return true

view.setOnLongClickListener {
    Toast.makeText(this,"This is a long click",Toast.LENGTH_SHORT).show(); 
    true
}
Chandan
  • 5,376
  • 1
  • 4
  • 16