Если ваша цель - установить связь между MainActivity
и Keyboard
, тогда обратный вызов будет работать нормально. Вы можете реализовать это так:
typealias KeyboardCallback = (Button) -> Unit
// Do not recommend doing this, it's for the example only
// It's probably better parsing the keyboard input as Char or Int
enum class Button {
A, B, C, D
}
class Keyboard {
private var callback : KeyboardCallback? = null
fun onKeyPressedListener(listener: KeyboardCallback) {
callback = listener
}
fun onClick(button: Button) {
// forward this action to the class that contains me
callback?.invoke(button)
}
}
class MainActivity {
val keyboard = Keyboard()
keyboard.onKeyPressedListener { key: Button ->
// parse buttons here
}
// Somewhere else (Will call the callback)
keyboard.onClick(Button.A)
}
Но если вам нужно слушать Клавиатуру из нескольких мест, то эта реализация не будет работать, потому что как только вы зарегистрируете второй обратный вызов, первый становится устаревшим (вы теряете ссылку на него, поскольку переменная callback
может содержать только одного слушателя), вы можете увидеть эту проблему здесь .
Если это нормально для вашей реализации, тогда выполните это (это известно как Образец Команды **). Если это не так, то вам нужно реализовать Observable / Observer Pattern , который был бы больше похож на это:
typealias KeyboardCallback = (Button) -> Unit
// Do not recommend doing this, it's for the example only
// It's probably better parsing the keyboard input as Char
enum class Button {
A, B, C, D
}
class Keyboard {
private val listeners = ArrayList<KeyboardCallback>()
fun onKeyPressedListener(listener: KeyboardCallback) {
callback.add(listener)
}
fun onClick(button: Button) {
// forward this action to the class that contains me
for (callback in listeners) {
callback(button)
}
}
}
class MainActivity {
val keyboard = Keyboard()
keyboard.onKeyPressedListener { key: Button ->
// parse buttons here
}
keyboard.onKeyPressedListener { another: Button ->
// added another listener
}
// Somewhere else (Will call the callback)
keyboard.onClick(Button.A)
}
Я сделал простой пример для наблюдаемого в этом kotlin детская площадка .
** Ну, не совсем, это упрощенная версия, поскольку шаблон команды реализован с использованием интерфейса и класс для представления «команда / обратный вызов», и этот класс может хранить произвольное состояние, которое не может указатель функции.