有没有办法观察何时调用另一个 class 的方法?
Is there a way to observe when a method from another class is called?
我想要一个具有不同按钮的自定义键盘 class。这个 class 将在每个按钮被调用时实现 onClick 监听器,但我想要另一个 class 来处理这个事件。例如:
class Keyboard {
Button A
Button B
...
fun onClick() {
// forward this action to the class that contains me
}
}
class MainActivity {
val keyboard = Keyboard()
keyboard.onClickListener {
// handle the click events
}
}
如何解决这个问题?
- 在键盘 class
中创建属性 clickListener
- 为此属性创建setter
- 在
Keyboard
的 onCLick 方法中调用 clickListener?.onClick(buttonClicked)
其中 buttonClicked
是键盘上被点击的按钮
- 在您的
MainActivity
中设置侦听器并处理 clickEvent
示例:
class Keyboard {
private var clickListener: View.OnClickListener? = null
fun setListener(listener: View.OnClickListener) {
clickListener = listener
}
fun onClick() {
clickListener?.onClick(buttonClicked) // pass button which was clicked
}
}
class MainActivity {
private val keyboard = Keyboard()
init {
keyboard.setListener(View.OnClickListener {
//do something
//it -> button which was clicked
})
}
}
如果您的 objective 是在 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
variable can only hold one listener), 可以看到这个问题here.
如果这对你的实施来说没问题,那就去做吧(它被称为 Command Pattern**). If it's not, then you need to implement the 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)
}
中为 observable 做了一个简单的例子
** 嗯,不完全是,它是它的简化版本,因为命令模式是使用 接口 和 class 实现的表示"command/callback",class可以存储任意状态,函数指针不能。
我想要一个具有不同按钮的自定义键盘 class。这个 class 将在每个按钮被调用时实现 onClick 监听器,但我想要另一个 class 来处理这个事件。例如:
class Keyboard {
Button A
Button B
...
fun onClick() {
// forward this action to the class that contains me
}
}
class MainActivity {
val keyboard = Keyboard()
keyboard.onClickListener {
// handle the click events
}
}
如何解决这个问题?
- 在键盘 class 中创建属性
- 为此属性创建setter
- 在
Keyboard
的 onCLick 方法中调用clickListener?.onClick(buttonClicked)
其中buttonClicked
是键盘上被点击的按钮 - 在您的
MainActivity
中设置侦听器并处理 clickEvent
clickListener
示例:
class Keyboard {
private var clickListener: View.OnClickListener? = null
fun setListener(listener: View.OnClickListener) {
clickListener = listener
}
fun onClick() {
clickListener?.onClick(buttonClicked) // pass button which was clicked
}
}
class MainActivity {
private val keyboard = Keyboard()
init {
keyboard.setListener(View.OnClickListener {
//do something
//it -> button which was clicked
})
}
}
如果您的 objective 是在 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
variable can only hold one listener), 可以看到这个问题here.
如果这对你的实施来说没问题,那就去做吧(它被称为 Command Pattern**). If it's not, then you need to implement the 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)
}
中为 observable 做了一个简单的例子
** 嗯,不完全是,它是它的简化版本,因为命令模式是使用 接口 和 class 实现的表示"command/callback",class可以存储任意状态,函数指针不能。