Is there a simple way to convert lambda into a full expression in Kotlin with Android Studio 3.5.1?

Viewed 434

The code in popup.setOnMenuItemClickListener is lambda expression, the function of the code is to show a popup menu.

It's hard to understand lambda expression sometimes.

Is there a simple way to convert a lambda into a full expression ? Is there some utilities to do that?

Code

 private fun showPopup(v: View, mContext: Context) {
        val popup = PopupMenu(mContext, v)
        popup.inflate(R.menu.menu_popup_more)

        popup.setOnMenuItemClickListener {
             when (it.itemId) {
                   R.id.MenuMoreAbout->{
                    requireActivity().openActivity<UIAbout>()
                   }
             }
            true  // Why do I need add 'true'
        }
        popup.show()
    }
1 Answers

Is there a simple way to convert a lambda into a full expression ?

Yes there is! First position the cursor on the first curly brace

                     Position your cursor at this character
                                 |
                                 v

popup.setOnMenuItemClickListener {
    when (it.itemId) {
        R.id.MenuMoreAbout->{
            requireActivity().openActivity<UIAbout>()
        }
    }
    true  // Why do I need add 'true'
}

then type Alt+Enter (Option+Enter for Mac) to bring up the Quick Fix menu. Select Convert to anonymous function. That will turn the code into the following:

popup.setOnMenuItemClickListener(fun(it: MenuItem): Boolean {
    when (it.itemId) {
        R.id.MenuMoreAbout -> {
            requireActivity().openActivity<UIAbout>()
        }
    }
    return true
})

which is clearer for someone that is new to Kotlin syntax.

As can be seen, your true expression was the return value of the lambda. In Kotlin, the return value of a lambda is the value of the last expression in the lambda. If you prefer, you can make this explicit by replacing

true  // Why do I need add 'true'

with

return@setOnMenuItemClickListener true

in your original code. See official docs for Return at Labels for more information.

The reason a Boolean has to be returned is because the lambda is for the following Java interface which is the type of the argument to setOnMenuItemClickListener(OnMenuItemClickListener)

    public interface OnMenuItemClickListener {
        boolean onMenuItemClick(MenuItem item);
    }

As you can see, onMenuItemClick(MenuItem) returns a boolean (which is converted to Boolean in Kotlin). So the lambda must also return a Boolean.

Related