Преобразование SAM в Kotlin (лямбда-выражение) - PullRequest
1 голос
/ 13 апреля 2020

У меня есть следующий функциональный интерфейс, определенный в Java.

interface OnButtonSwitchedListener {
    fun onButtonSwitched(isLogin: Boolean)
}

Теперь проблема в том, что когда я должен использовать это в Kotlin, мне нужно создать анонимный объект для использования этого интерфейса, например,

binding.button.setOnButtonSwitched(object: OnButtonSwitchedListener{
                    override fun onButtonSwitched(isLogin: Boolean) {
                        binding.root
                            .setBackgroundColor(
                                ContextCompat.getColor(
                                    this@AuthActivity,
                                     if(isLogin) R.color.colorPrimary else R.color.lb_secondPage))
                    }
                })

Однако, синтаксис Java8 намного умнее,

binding.button.setOnButtonSwitched(isLogin -> {
                binding.root
                    .setBackgroundColor(
                        ContextCompat.getColor(
                        this,
                        isLogin ? R.color.colorPrimary : R.color.secondPage));
            })

Есть ли способ, я тоже могу написать подобное лямбда-выражение в Kotlin?

Я попробовал следующее, но выдает ошибку, показанную на вставленном изображении.

setOnButtonSwitched{isLogin -> {binding.root
                    .setBackgroundColor(
                        ContextCompat.getColor(
                            this@AuthActivity,
                            if(isLogin) R.color.colorPrimary else R.color.lb_secondPage))}}

Error message in Android Studio

Ответы [ 2 ]

2 голосов
/ 13 апреля 2020

Преобразования SAM будут введены в Kotlin 1.4 , до тех пор пока вам не придется вручную реализовывать интерфейс и переопределить функцию.

Они будут выглядеть одинаково как обычная лямбда:

binding.button.setOnButtonSwitched{ isLogin ->
    ...
}

PS: ожидаемый выпуск Kotlin 1.4 ожидается весной 2020 года


для текущей версии Kotlin 1.3.xx

Если вы используете их слишком часто, попробуйте сейчас создать служебную функцию:

fun OnButtonSwitchedListener(block: (Boolean) -> Unit) =
    object : OnButtonSwitchedListener {
        override fun onButtonSwitched(isLogin: Boolean) {
            block(isLogin)
        }
    }

Теперь вы можете вызывать так:

binding.button.setOnButtonSwitched(OnButtonSwitchedListener { isLogin ->
   ... // your code
})
0 голосов
/ 13 апреля 2020

Предполагая, что интерфейс действительно в Java, а не в Kotlin (void onButtonSwitched(boolean isLogin) вместо fun onButtonSwitched(isLogin: Boolean)), вам необходимо удалить {} вокруг тела лямбды (часть после isLogin ->):

setOnButtonSwitched { isLogin -> binding.root
                    .setBackgroundColor(
                        ContextCompat.getColor(
                            this@AuthActivity,
                            if(isLogin) R.color.colorPrimary else R.color.lb_secondPage)) }

Проблема в том, что, как вы написали, получается лямбда, которая не вызывает binding.root.setBackgroundColor(...), а вместо этого создает другую лямбду { binding.root.setBackgroundColor(...) } и выбрасывает ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...