4

I have a Custom Dialog class defined follow builder pattern. I have no problem with my code. But now I want to rebuild to be able to use on java 8 lambda

CustomDialogList.kt

class CustomDialogList(context: Context,
                       private var title: Int?,
                       private var icon: Int?,
                       private var map: Map<String, Any>,
                       private var listner: OnItemClickListener) : Dialog(context) {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.custom_dialog_list)
        txtTitle.text = context.getString(title!!)
        txtTitle.setCompoundDrawablesWithIntrinsicBounds(icon!!, 0, 0, 0)

        val listString: MutableList<String> = mutableListOf()
        val listObject: MutableList<Any> = mutableListOf()
        for ((k, v) in map) {
            listString.add(k)
            listObject.add(v)
        }

        val adapter = ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, listString)
        listView.adapter = adapter
        listView.setOnItemClickListener { _, _, i, _ ->
            listner.onClickResult(this, listObject[i], listString[i], i)
        }
    }

    interface OnItemClickListener {
        fun onClickResult(dialog: CustomDialogList, obj: Any?, text: String, position: Int)
    }

    class Builder(private var context: Context) {

        private var listner: OnItemClickListener? = null
        private var title: Int? = null
        private var icon: Int? = null
        private var map: Map<String, Any> = mapOf()

        fun withTitle(title: Int): Builder {
            this.title = title
            return this
        }

        fun withIcon(icon: Int): Builder {
            this.icon = icon
            return this
        }

        fun withMap(map: Map<String, Any>): Builder {
            this.map = map
            return this
        }

        fun setOnItemClick(listner: OnItemClickListener): Builder {
            this.listner = listner
            return this
        }

        fun show() = CustomDialogList(context, title, icon, map, listner!!).show()
    }
}

The syntax which I have after define

CustomDialogList.Builder(this)
                .withTitle(R.string.add)
                .withIcon(R.drawable.ic_add)
                .withMap(mapOf())
                .setOnItemClick(object : CustomDialogList.OnItemClickListener {
                    override fun onClickResult(dialog: CustomDialogList, obj: Any?, text: String, position: Int) {
                        // do something
                        dialog.dismiss()
                    }
                })
                .show()

And here is an example that I want to build

CustomDialogList.Builder(this)
                .withTitle(R.string.add)
                .withIcon(R.drawable.ic_add)
                .withMap(mapOf())
                .setOnItemClick({ dialog, obj, text, position ->
                    // do something
                    dialog.dismiss()
                })
                .show()

This is first time I post question, hope everyone will excuse me for my bad english. And thank you for anyone can help me :)

Bao Tran
  • 43
  • 1
  • 4

1 Answers1

1

KT-7770: SAM does not work for interfaces defined in Kotlin.

In other words, the lambda expression

{ dialog, obj, text, position -> ... }

can be a Java functional interface or a Kotlin function, but not a Kotlin functional interface.

If you delete your OnItemClickListener interface and write

typealias OnItemClickListener = (CustomDialogList, Any?, String, Int) -> Unit

at the top-level, or modify the type signatures, your second example will work (and your first one will fail). If you instead define the interface in Java, both will work.

ephemient
  • 198,619
  • 38
  • 280
  • 391